Thanks to Saffith for helping finalize and debug this one.
This is utility script, pretty well described by the in-code comments.
NOTE: You must specify locations for your blocks using the upper-left corner of the tile.
Code:
// ===============================================
// multiblock_trigger - This FFC will change combo
// depending on whether certain combos on Layer 0
// are unwalkable. As input, this FFC takes eight
// integers which represent four (X,Y) pairs that the
// multiblock checks for walkability. When all are
// unwalkable, the combo of this FFC will increase by
// one and a secret noise will chime. When any are
// walkable, they will revert back to their original
// combo and not make a chime. By default, the original
// combo used by this FFC mimics unwalkability.
//
// USE - You can use the multiblock trigger to require
// Link to push up to four blocks into position. For
// less than four, just set all of the inputs to permanently
// unwalkable combos, like a dungeon wall, or set them
// all to the same location. Because this FFC reverts
// when the tiles are not walkable, it can also be used
// to create "pressure-sensitive" triggers that must be
// held down by a block and will deactive when the block
// moves away.
// ===============================================
ffc script multiblock_trigger{
// CONSTANTS - Change to change this FFC's behavior
int walkable = 1; // Whether or not the starting
// combo for this FFC is walkable
// or not. For instance, a closed
// door should start unwalkable.
// 0 = walkable
// 1 = unwalkable
// VARIABLES - Do not change!
int state = 0; // Current state of the FFC.
// 0 = untriggered
// 1 = triggered
void run (int block1_x, int block1_y, int block2_x, int block2_y,
int block3_x, int block3_y,int block4_x, int block4_y){
state = 0;
while(true){
if(state == 0){
// Check to see if all blocks in position
if (!canMove(block1_x, block1_y) &&
!canMove(block2_x, block2_y) &&
!canMove(block3_x, block3_y) &&
!canMove(block4_x, block4_y)){
this->Data = this->Data + 1;
Game->PlaySound(27);
state = 1;
}
// Simulate unwalkability
if(walkable == 1){
if( (Link->InputUp) && (Link->Y < this->Y + 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y > this->Y)){Link->InputUp = false;}
if( (Link->InputDown) && (Link->Y > this->Y - 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y < this->Y)){Link->InputDown = false;}
if( (Link->InputLeft) && (Link->X < this->X + 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X > this->X)){Link->InputLeft = false;}
if( (Link->InputRight) && (Link->X > this->X - 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X < this->X)){Link->InputRight = false;}
}
} // end of state 0
if (state == 1){
// Check to see if a block has moved
if (canMove(block1_x, block1_y) ||
canMove(block2_x, block2_y) ||
canMove(block3_x, block3_y) ||
canMove(block4_x, block4_y)){
this->Data = this->Data - 1;
state = 0;
}
} // end of state 1
Waitframe();
} // end of while loop
} // end of void run
// Collision Detection Function (Thanks Saffith!)
bool canMove(int x, int y)
{
if(x<0 || x>240 || y<0 || y>160)
return false;
return Screen->ComboS[y+(x>>4)]==0;
}
} // end of ffc script