In building my sand digging script I've ran into a few bugs that I'm having trouble making any sense of. The code compiles fine and work correctly other than these bugs.
Engine: 2.55 Alpha 83
The code works by checking if Link is using the item "diggingclaws" on the position of a combo running one of the three scripts. The combos are then either changed to 0 (if removed) or to another combo of a sandwall type depending on it's position and neighbors.
The problems I'm having other than the script failing to run when a combo is changed, which I have traced to be the engine, are as follows: (from the ZScript Debug Console)
When digging up I get the error after 3 or more triggers: "Combo script 4 (SandWall_Top): Invalid pointer (0) passed to array (don't change the values of your array pointers)" repeating or the game will completely crash.
When digging down I get the error after 3 or more tiggers: "Combo script 3 (SandWall_Base): Invalid position [-1] used to read to 'Screen->ComboT[]'"
When digging to the side I get the error on the first trigger: "Combo script 3 (SandWall_Base): Invalid position [-1] used to read to 'Screen->ComboT[]'" and "Combo script 6 (): Invalid ZASM command 22629 reached" (repeats with various numbers) and "Combo script 6 (): FFSScript::InvalidError - Invalid pointer (91444) passed to array (don't change the values of your array pointers)"
Uses ffcscript.zh
//Sand wall script. const int DIGGINGCLAWS = 144; const int SANDWALL_COMBO = 142; const int SANDWALL_TOPFRONT = 98; const int SANDWALL_TOPBACK = 99; const int SANDWALL_BASE = 100; const int SANDWALL_TOP = 101; const int SANDWALL_MIDDLE = 102; const int SANDWALL_FILL = 105; //combos listed: Left | Middle | Right | Alone const int SANDWALL_BC[4] = {2540, 2541, 2542, 2543}; const int SANDWALL_MC[4] = {2536, 2537, 2538, 2539}; const int SANDWALL_TC[4] = {2532, 2533, 2534, 2535}; const int SANDWALL_TFC[4] = {2528, 2529, 2530, 2531}; const int SANDWALL_TFIC[4] = {2524, 2525, 2526, 2527}; const int SANDWALL_TBC[4] = {2520, 2521, 2522, 2523}; int SandWall_ComboFinder(int section, int pos) { bool left = false; bool right = false; //Find combo to left and right. if(GetLayerComboT(0, pos-1) == SANDWALL_COMBO && GetLayerComboI(0, pos-1) == section) left = true; if(GetLayerComboT(0, pos+1) == SANDWALL_COMBO && GetLayerComboI(0, pos+1) == section) right = true; switch(section) { case SANDWALL_BASE: if(left && right) return SANDWALL_BC[1]; else if(left) return SANDWALL_BC[2]; else if(right) return SANDWALL_BC[0]; else return SANDWALL_BC[3]; break; case SANDWALL_TOP: if(left && right) return SANDWALL_TC[1]; else if(left) return SANDWALL_TC[2]; else if(right) return SANDWALL_TC[0]; else return SANDWALL_TC[3]; break; case SANDWALL_TOPFRONT: if(left && right) return SANDWALL_TFC[1]; else if(left) return SANDWALL_TFC[2]; else if(right) return SANDWALL_TFC[0]; else return SANDWALL_TFC[3]; break; case SANDWALL_TOPBACK: if(left && right) return SANDWALL_TBC[1]; else if(left) return SANDWALL_TBC[2]; else if(right) return SANDWALL_TBC[0]; else return SANDWALL_TBC[3]; break; case SANDWALL_FILL: if(left && right) return SANDWALL_TFIC[1]; else if(left) return SANDWALL_TFIC[2]; else if(right) return SANDWALL_TFIC[0]; else return SANDWALL_TFIC[3]; break; case SANDWALL_MIDDLE: if(left && right) return SANDWALL_MC[1]; else if(left) return SANDWALL_MC[2]; else if(right) return SANDWALL_MC[0]; else return SANDWALL_MC[3]; break; } } void SandWall_Update(int position) { int inherent; inherent = GetLayerComboI(0, position-1); if(GetLayerComboT(0, position-1) == SANDWALL_COMBO) { if(inherent == SANDWALL_TOP) SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_TOP, position-1)); else if(inherent == SANDWALL_TOPBACK) SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_TOPBACK, position-1)); else if(inherent == SANDWALL_TOPFRONT) SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_TOPFRONT, position-1)); else if(inherent == SANDWALL_FILL) SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_FILL, position-1)); else if(inherent == SANDWALL_MIDDLE) SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_MIDDLE, position-1)); else //Base SetLayerComboD(0, position-1, SandWall_ComboFinder(SANDWALL_BASE, position-1)); } inherent = GetLayerComboI(0, position+1); if(GetLayerComboT(0, position+1) == SANDWALL_COMBO) { if(inherent == SANDWALL_TOP) SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_TOP, position+1)); else if(inherent == SANDWALL_TOPBACK) SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_TOPBACK, position+1)); else if(inherent == SANDWALL_TOPFRONT) SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_TOPFRONT, position+1)); else if(inherent == SANDWALL_FILL) SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_FILL, position+1)); else if(inherent == SANDWALL_MIDDLE) SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_MIDDLE, position+1)); else //Base SetLayerComboD(0, position+1, SandWall_ComboFinder(SANDWALL_BASE, position+1)); } } combodata script SandWall_Base { void run() { int height = 0; int depth = 0; int position; while(true) { if(((Hero->X+8 >= this->PosX() && Hero->X+8 <= this->PosX()+15) && (Hero->Y >= this->PosY() && Hero->Y <= this->PosY()+15) && Hero->Dir == DIR_UP) || ((Hero->X-8 >= this->PosX() && Hero->X <= this->PosX()+16) && (Hero->Y+8 >= this->PosY() && Hero->Y+8 <= this->PosY()+15) && Hero->Dir == DIR_LEFT) || ((Hero->X+16 >= this->PosX() && Hero->X+24 <= this->PosX()+15) && (Hero->Y+8 >= this->PosY() && Hero->Y+8 <= this->PosY()+15) && Hero->Dir == DIR_RIGHT)) { if(GetEquipmentB() == DIGGINGCLAWS && Hero->PressB) { //Find Height do { height++; if(height > 11) Quit(); }while(GetLayerComboI(0, ComboAt(this->PosX(), this->PosY()+(height*16*-1))) != SANDWALL_TOPFRONT && GetLayerComboI(0, ComboAt(this->PosX(), this->PosY()+(height*16*-1))) != SANDWALL_TOP) //Find depth if(GetLayerComboI(0, ComboAt(this->PosX(), this->PosY()+(height*16*-1))) != SANDWALL_TOP) { do { depth++; if(depth > 11) Quit(); }while(GetLayerComboI(0, ComboAt(this->PosX(), (this->PosY()+(height*16*-1))+(depth*16*-1))) != SANDWALL_TOPBACK) } //Change Combos, starting from top to base. if(depth == 0) { for(height; height >= 0; height--) { position = ComboAt(this->PosX(), this->PosY()+(height*16*-1)); SetLayerComboD(0, position, 0); SandWall_Update(position); } Quit(); } else if(depth == 1) { //Top back. position = ComboAt(this->PosX(), (this->PosY()+(height*16*-1))+(depth*16*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOP, position)); SandWall_Update(position); //Middle sections. for(height; height > 1; height--) { position = ComboAt(this->PosX(), this->PosY()+(height*16*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_MIDDLE, position)); SandWall_Update(position); } //New Base. position = ComboAt(this->PosX(), this->PosY()-16); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_BASE, position)); SandWall_Update(position); //Old Base. position = this->Pos(); SetLayerComboD(0, position, 0); SandWall_Update(position); Quit(); } else { //Top front. position = ComboAt(this->PosX(), (this->PosY()+(height*16*-1))-16); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOPFRONT, position)); SandWall_Update(position); //Middle Sections. for(height; height > 1; height--) { position = ComboAt(this->PosX(), this->PosY()+(height*16*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_MIDDLE, position)); SandWall_Update(position); } //New Base. position = ComboAt(this->PosX(), this->PosY()-16); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_BASE, position)); SandWall_Update(position); //Old Base. position = this->Pos(); SetLayerComboD(0, position, 0); SandWall_Update(position); Quit(); } } } Waitframe(); } } } combodata script SandWall_Top { void run() { int position; int height = 0; while(true) { if(((Hero->X+8 >= this->PosX() && Hero->X+8 <= this->PosX()+15) && (Hero->Y+16 >= this->PosY() && Hero->Y+24 <= this->PosY()+16) && Hero->Dir == DIR_DOWN)) { if(GetEquipmentB() == DIGGINGCLAWS && Hero->PressB) { position = this->Pos(); if(GetLayerComboI(0, position) == SANDWALL_TOPBACK) { //Old Top. SetLayerComboD(0, position, 0); SandWall_Update(position); //New Top. position = ComboAt(this->PosX(), this->PosY()+16); if(GetLayerComboI(0, position) == SANDWALL_TOPFRONT) { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOP, position)); SandWall_Update(position); } else { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOPBACK, position)); SandWall_Update(position); } Quit(); } else { //Find Height. do { height++; if(height > 11) Quit(); }while(GetLayerComboI(0, ComboAt(this->PosX(), this->PosY()+(16*height))) != SANDWALL_BASE) for(height; height >= 0; height--) { position = ComboAt(this->PosX(), this->PosY()+(16*height)); SetLayerComboD(0, position, 0); SandWall_Update(position); } Quit(); } } } Waitframe(); } } } combodata script SandWall_Fill { void run() { int height = 0; int X = this->PosX(); int Y = this->PosY(); int position; while(true) { if(((Hero->X-8 >= this->PosX() && Hero->X <= this->PosX()+16) && (Hero->Y+8 >= this->PosY() && Hero->Y+8 <= this->PosY()+15) && Hero->Dir == DIR_LEFT) || ((Hero->X+16 >= this->PosX() && Hero->X+24 <= this->PosX()+15) && (Hero->Y+8 >= this->PosY() && Hero->Y+8 <= this->PosY()+15) && Hero->Dir == DIR_RIGHT)) { if(GetEquipmentB() == DIGGINGCLAWS && Hero->PressB) { //Find height do { Y += 16; position = ComboAt(X, Y); if(Y > 176) Quit(); }while(GetLayerComboI(0, position) != SANDWALL_TOPFRONT) do { height++; position = ComboAt(X, Y+(height*16)); if(height > 11) Quit(); }while(GetLayerComboI(0, position) != SANDWALL_BASE) //Check height Y = this->PosY(); if(GetLayerComboT(0, ComboAt(X, Y+(16*height*-1))) == SANDWALL_COMBO) { if(GetLayerComboI(0, ComboAt(X, Y+(16*height*-1))) == SANDWALL_TOPBACK) { for(height; height >= 0; height--) { position = ComboAt(X, Y+(16*height*-1)); SetLayerComboD(0, position, 0); SandWall_Update(position); } //Set New Top. position = ComboAt(X, Y+16); if(GetLayerComboI(0, position) == SANDWALL_TOPFRONT) { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOP, position)); SandWall_Update(position); } else { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOPBACK, position)); SandWall_Update(position); } Quit(); } else { //New top Back. position = ComboAt(X, Y+(16*height*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOPFRONT, position)); SandWall_Update(position); height -= 1; //New Middle. for(height; height > 1; height--) { position = ComboAt(X, Y+(16*height*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_MIDDLE, position)); SandWall_Update(position); } //New Base. position = ComboAt(X, Y+(16*height*-1)); SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_BASE, position)); SandWall_Update(position); //Remove Fill. position = this->Pos(); SetLayerComboD(0, position, 0); SandWall_Update(position); //Set New Top. position = ComboAt(X, Y+16); if(GetLayerComboI(0, position) == SANDWALL_TOPFRONT) { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOP, position)); SandWall_Update(position); } else { SetLayerComboD(0, position, SandWall_ComboFinder(SANDWALL_TOPBACK, position)); SandWall_Update(position); } Quit(); } } } } Waitframe(); } } }