C-Dawg
10-30-2006, 12:37 PM
I'm at work, so I can't test this code yet. But I thought I'd post it anyway so the community can take a look and correct any glaring oversight in the algorithim. (Or perhaps someone more talented than I can be inspired.)
Multiblock Triggers:
int distancesq(int x1, int x2, int y1, int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
// ===============================================
// 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 block_3y,int block4_x, int block_4y){
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;
PlaySound(27);
state = 1;
}
// Simulate unwalkability
if(walkable == 1){
if( (Link->InputUp) && (Link->Y << this->Y + 16) &&
(Link-Y >> this->Y)){Link->Y++;}
if( (Link->InputDown) && (Link->Y >> this->Y - 16) &&
(Link-Y << this->Y)){Link->Y--;}
if( (Link->InputLeft) && (Link->X << this->X + 16) &&
(Link-X >> this->X)){Link->X++;}
if( (Link->InputRight) && (Link->X >> this->X - 16) &&
(Link-X << this->X)){Link->X--;}
}
} // 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
} // end of while loop
} // end of void run
} // end of ffc script
Link_Pusher ideally functions like Blocky from Adventures of Lolo.
int distancesq(int x1, int x2, int y1, int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
// =======================================
// Link_Pusher - The FFC will move towards
// Link, though it will not pass through
// unwalkable combos on layer 0. When it
// reaches Link, it pushes him in whatever
// direction it is moving.
// =======================================
ffc script link_pusher {
int x;
int y;
void run() {
while(true)
{
x = this->X;
y = this->Y;
int dist = distancesq(Link->X, this->X, Link->Y, this->Y);
this->Vx = (Link->X - x)*Abs((Link->X-x))/dist;
this->Vy = (Link->Y - y)*Abs((Link->Y-y))/dist;
// Don't move if it would move into an unwalkable block.
if ( (!canMove(this->X, this->Y + 16)) && (this->Vy >> 0)){
this->Vy = 0;
}
if ( (!canMove(this->X, this->Y - 16)) && (this->Vy << 0)){
this->Vy = 0;
}
if ( (!canMove(this->X + 16, this->Y)) && (this->Vx >> 0)){
this->Vx = 0;
}
if ( (!canMove(this->X - 16, this->Y)) && (this->Vx << 0)){
this->Vx = 0;
}
// Push Link if moving next to him. Check if the FFC is
// within one tile of Link, and is moving towards him. Then
// checks whether Link would be pushed into a solid block.
// If conditions are satisfied, Link is pushed back in the
// direction of the FFC's movement. If Link moves against
// the pusher, he's forced back more heavily.
if ( (this->X >> Link->X) && (this->X << Link->X + 16) &&
(this->Vx << 0)){
if (canMove(Link->X - 16)){
Link->X = Link->X -1;
if (Link->InputRight == true){Link->X = Link->X-1;}
}
}
if ( (this->X << Link->X) && (this->X >> Link->X - 16) &&
(this->Vx >> 0)){
if (canMove(Link->X + 16)){
Link->X = Link->X + 1;
if (Link->InputLeft == true){Link->X = Link->X+1;}
}
}
if ( (this->Y << Link->Y) && (this->Y >> Link->Y - 16) &&
(this->Vy >> 0)){
if (canMove(Link->Y + 16)){
Link->Y = Link->Y + 1;
if (Link->InputUp == true){Link->Y = Link->Y+1;}
}
}
if ( (this->Y >> Link->Y) && (this->Y << Link->Y + 16) &&
(this->Vy << 0)){
if (canMove(Link->Y - 16)){
Link->Y = Link->Y - 1;
if (Link->InputDown == true){Link->Y = Link->Y-1;}
}
}
Waitframe();
} // end of while loop
} // end of void run
// Collision detection function
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
Multiblock Triggers:
int distancesq(int x1, int x2, int y1, int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
// ===============================================
// 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 block_3y,int block4_x, int block_4y){
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;
PlaySound(27);
state = 1;
}
// Simulate unwalkability
if(walkable == 1){
if( (Link->InputUp) && (Link->Y << this->Y + 16) &&
(Link-Y >> this->Y)){Link->Y++;}
if( (Link->InputDown) && (Link->Y >> this->Y - 16) &&
(Link-Y << this->Y)){Link->Y--;}
if( (Link->InputLeft) && (Link->X << this->X + 16) &&
(Link-X >> this->X)){Link->X++;}
if( (Link->InputRight) && (Link->X >> this->X - 16) &&
(Link-X << this->X)){Link->X--;}
}
} // 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
} // end of while loop
} // end of void run
} // end of ffc script
Link_Pusher ideally functions like Blocky from Adventures of Lolo.
int distancesq(int x1, int x2, int y1, int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
// =======================================
// Link_Pusher - The FFC will move towards
// Link, though it will not pass through
// unwalkable combos on layer 0. When it
// reaches Link, it pushes him in whatever
// direction it is moving.
// =======================================
ffc script link_pusher {
int x;
int y;
void run() {
while(true)
{
x = this->X;
y = this->Y;
int dist = distancesq(Link->X, this->X, Link->Y, this->Y);
this->Vx = (Link->X - x)*Abs((Link->X-x))/dist;
this->Vy = (Link->Y - y)*Abs((Link->Y-y))/dist;
// Don't move if it would move into an unwalkable block.
if ( (!canMove(this->X, this->Y + 16)) && (this->Vy >> 0)){
this->Vy = 0;
}
if ( (!canMove(this->X, this->Y - 16)) && (this->Vy << 0)){
this->Vy = 0;
}
if ( (!canMove(this->X + 16, this->Y)) && (this->Vx >> 0)){
this->Vx = 0;
}
if ( (!canMove(this->X - 16, this->Y)) && (this->Vx << 0)){
this->Vx = 0;
}
// Push Link if moving next to him. Check if the FFC is
// within one tile of Link, and is moving towards him. Then
// checks whether Link would be pushed into a solid block.
// If conditions are satisfied, Link is pushed back in the
// direction of the FFC's movement. If Link moves against
// the pusher, he's forced back more heavily.
if ( (this->X >> Link->X) && (this->X << Link->X + 16) &&
(this->Vx << 0)){
if (canMove(Link->X - 16)){
Link->X = Link->X -1;
if (Link->InputRight == true){Link->X = Link->X-1;}
}
}
if ( (this->X << Link->X) && (this->X >> Link->X - 16) &&
(this->Vx >> 0)){
if (canMove(Link->X + 16)){
Link->X = Link->X + 1;
if (Link->InputLeft == true){Link->X = Link->X+1;}
}
}
if ( (this->Y << Link->Y) && (this->Y >> Link->Y - 16) &&
(this->Vy >> 0)){
if (canMove(Link->Y + 16)){
Link->Y = Link->Y + 1;
if (Link->InputUp == true){Link->Y = Link->Y+1;}
}
}
if ( (this->Y >> Link->Y) && (this->Y << Link->Y + 16) &&
(this->Vy << 0)){
if (canMove(Link->Y - 16)){
Link->Y = Link->Y - 1;
if (Link->InputDown == true){Link->Y = Link->Y-1;}
}
}
Waitframe();
} // end of while loop
} // end of void run
// Collision detection function
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