const int CF_MATRIX_PUZZLE_PIECE = 98;//Combo flag to be places on combos that are a part of a puzzle.
const int SFX_MATRIX_PUZZLE_COMBO_CHANGE = 16; //Sound to play, when changing password combos by standing on combos and pressing A.
const int SFX_MATRIX_PUZZLE_SOLVED = 27; //Sound to play, when correct password is inputed.
const int TILE_MATRIX_FRAME = 17054;//Tile used to render prompt frame with instructions, along with combo underneath Link. 0 for no prompt drawing.
const int CSET_MATRIX_FRAME = 7;//Cset used to render frame.
const int MATRIX_DEBUG_SOLUTION = 0; //>0 = render internal solutution. Used for script debugging.
//Password lock Script5 : The Disconnected Matrix 5 - Up and Down.
//Stand on combos and press Ex1 and Ex2 to change specific combos. Input password to open secrets.
//Requires ffcscript.zh
//1. Set up sequence of combos to form password alphabet.
//2. Import and compile the script.
//3. Build the combination lock in it`s solved state. Flag every combo consisting the puzzle with CF_MATRIX_PUZZLE_PIECE.
//4. Place FFC anywhere in the screen. Assign the script to it and combo to first combo in password alphabet.
//5. Set "Run at Screen Init" and "Only Visible to Lens of Truth" flags.
// D0 - Set to > 0 to Allow using Lens of Truth to crack the code.
// D1 - Set to > 0 toallow input by standing on puzzle combos and pressing Ex1 and Ex2, with D1 set at alphabet size (number of characters consising the code). 0 to use other methods of changing the combos.
// D2 - Set to > 0 to replace all CF_MATRIX_PUZZLE_PIECE flags with Trigger->Self-only flags on init after defining intended puzzle solution.
// Needded if you use trigger flags for building password puzzles. You also need to set "Secrets are Temporary" screen flag.
// so secrets won`t open after hitting a trigger, then exiting and reentering screen.
// D3 - Screen layer to define puzzle solution. Use layer, other then 0, if you don`t want changes to layer 0.
// D4 - Tile rotating animation.
// D5 - Set to > 0 to allow wraparound when cycling combos in password (D1>0).
ffc script MatrixPasswordPuzzle5_0{
void run (int lensvis, int alphabet, int selftrigger, int layer, int rot, int wraparound){
if (Screen->State[ST_SECRET]) Quit();
//Process creating puzzle solution and resetting combination lock.
int solution[176];
int origcmb = this->Data;
this->Data = FFCS_INVISIBLE_COMBO;
int offset = 0;
int cmb=-1;
int slot=0;
for (int i=0; i<176; i++){
if (ComboFI(i, CF_MATRIX_PUZZLE_PIECE) || GetLayerComboF(layer, i)==CF_MATRIX_PUZZLE_PIECE|| GetLayerComboI(layer, i)==CF_MATRIX_PUZZLE_PIECE){
if (layer>0){
solution[i]=GetLayerComboD(layer, i) - origcmb;
}
else{
solution[i] = Screen->ComboD[i] - origcmb;
Screen->ComboD[i] = origcmb;
}
if (selftrigger>0) Screen->ComboF[i]=CF_SINGLE;
if (Screen->ComboS[i]>0)offset=-2;
}
else solution[i]= -1;
}
while(true){
if (alphabet>0){
cmb = ComboAt(CenterLinkX(), CenterLinkY()+offset);
if (TILE_MATRIX_FRAME>0 && solution[cmb]>=0){
MatrixDrawFrame(5, TILE_MATRIX_FRAME, Link->X-16, Link->Y-48, 3, 3, CSET_MATRIX_FRAME, OP_OPAQUE);
Screen->FastCombo(5, Link->X, Link->Y-32, Screen->ComboD[cmb], Screen->ComboC[cmb], OP_OPAQUE);
}
if (Link->PressEx1){//Process Auto-input
slot = Screen->ComboD[cmb]-origcmb;
if (solution[cmb] >= 0 && (wraparound || slot<alphabet)){
Game->PlaySound(SFX_MATRIX_PUZZLE_COMBO_CHANGE);
if (rot>0){
int newcmb = Screen->ComboD[cmb];
Screen->ComboD[cmb]=FFCS_INVISIBLE_COMBO;
for (int i=0; i<15; i++){
Screen->DrawCombo(1, ComboX(cmb), ComboY(cmb), newcmb, 1, 1, Screen->ComboC[cmb], -1, -1, ComboX(cmb),ComboY(cmb), 6*i, 1, 0, false, OP_OPAQUE);
Waitframe();
}
Screen->ComboD[cmb]= newcmb;
}
if (Screen->ComboD[cmb]<origcmb+alphabet)Screen->ComboD[cmb]++;
if (wraparound>0 && (Screen->ComboD[cmb]==origcmb+alphabet))Screen->ComboD[cmb]=origcmb;
}
}
if (Link->PressEx2){
slot = Screen->ComboD[cmb]-origcmb;
if (solution[cmb] >= 0 && (wraparound || slot>=0)){
Game->PlaySound(SFX_MATRIX_PUZZLE_COMBO_CHANGE);
if (rot>0){
int newcmb = Screen->ComboD[cmb];
Screen->ComboD[cmb]=FFCS_INVISIBLE_COMBO;
for (int i=0; i<15; i++){
Screen->DrawCombo(1, ComboX(cmb), ComboY(cmb), newcmb, 1, 1, Screen->ComboC[cmb], -1, -1, ComboX(cmb),ComboY(cmb), -6*i, 1, 0, false, OP_OPAQUE);
Waitframe();
}
Screen->ComboD[cmb]= newcmb;
}
if (Screen->ComboD[cmb]>=origcmb)Screen->ComboD[cmb]--;
if (wraparound>0 && (Screen->ComboD[cmb]<origcmb))Screen->ComboD[cmb]=origcmb+alphabet-1;
}
}
}
if (lensvis>0){
//Process cracking the code with Lens of Truth
if (UsingItem(I_LENS)){//Allow Lens of Truth to crack the code
for (int i=0; i<176; i++){
if (solution[i]>=0)
Screen->FastCombo(1, ComboX(i), ComboY(i), origcmb+solution[i], Screen->ComboC[i], OP_OPAQUE);
}
}
}
for (int i=0;i<=176;i++){
if (i==176){
Game->PlaySound(SFX_MATRIX_PUZZLE_SOLVED);
Screen->TriggerSecrets();
Screen->State[ST_SECRET]=true;
Quit();
}
else if (solution[i]<0) continue;
else if (Screen->ComboD[i] != (origcmb + solution[i])) break;
}
if (MATRIX_DEBUG_SOLUTION>0)DebugSolution(solution, origcmb);//debug
Waitframe();
}
}
}
void DebugSolution(int solution, int origcmb){
for (int i=0; i<176; i++){
if (solution[i]<0) continue;
if ((Screen->ComboD[i] == (origcmb + solution[i])))Screen->DrawInteger(2, ComboX(i), ComboY(i),0, 1,0 , -1, -1, solution[i], 0, OP_OPAQUE);
}
}
void MatrixDrawFrame(int layer, int tile, int posx, int posy, int sizex, int sizey, int CSet, int opacity){
int drawx = posx;
int drawy = posy;
int xoffset=0;
int yoffset=0;
for (int w=0; w<sizex; w++){
drawx = posx+16*w;
xoffset=0;
if (w>0)xoffset=1;
if (w==sizex-1) xoffset=2;
for (int h=0; h<sizey; h++){
drawy = posy+16*h;
yoffset=0;
if (h>0)yoffset=1;
if (h==sizey-1) yoffset=2;
Screen->FastTile(layer, drawx, drawy, tile +xoffset+20*yoffset, CSet, opacity);
}
}
}