PDA

View Full Version : Rolling Block



C-Dawg
11-01-2006, 04:05 PM
Here's another script that I did on lunch break at work. Havn't tested it yet. Still, every time I post one of these, Saffith comes and explains my misconceptions about ZScript. To continue the education for me and for anyone reading these threads, I present: the Rolling Block script.

What I think I'll do is modify my Multiblock_trigger script to detect either walkability OR the presense of another FFC. That way, you can make puzzles that require you to push a rolling block into position, ala Brainlord. I also recall OoT having some of these puzzles in the ice levels.



// ===============================================
// rolling_block = When pushed, this block will
// continue rolling until it hits another solid
// combo. Link needs to stand next to it and push
// for several tics to make it roll.
// Uses two combos, one for stationary, and
// a second for rolling. Use the FFC data to set
// whether Link needs the Bracelet #1 or #2 to
// roll the block.
// 0 = No bracelet needed
// 1 = Need #1 bracelet
// 2 = Need #2 bracelet
// ===============================================

ffc script rolling_block{

// CONSTANTS - use to change behavior

int speed = 2; // The speed at which the
// FFC rolls.

int delay = 5; // How many tics Link must
// push against the ffc
// before it moves.

// VARIABLES - Do not change!

int state = 0; // Current state of the FFC.
// 0 = stationary
// 1 = rolling

int roll_x =0; // Used to determine the direction
int roll_y =0; // of the roll.

int push_counter = delay;

void run (int heavy){

while(true){



if(state == 0){

// First, check if Link has the appropriate bracelet. Then,
// check for Link pushing this combo. If he's been
// pushing it constantly for push_counter tics,
// start it in motion in the appropriate direction.

if( (heavy == 0) || ((heavy == 1) && (Link->Item[19])) || ((heavy == 2) && (Link->Item[56])) ){

if( (Link->InputUp) && (Link->Y << this->Y + 16) &&
(Link-Y >> this->Y)){
if (push_counter = 0){
state = 0;
roll_x = 0;
roll_y = -1;
this->Data++;
}
else { push_counter--;}
}
else{
if( (Link->InputDown) && (Link->Y >> this->Y - 16) &&
(Link-Y << this->Y)){
if (push_counter = 0){
state = 0;
roll_x = 0;
roll_y = 1;
this->Data++;
}
else { push_counter--;}
}
else{
if( (Link->InputLeft) && (Link->X << this->X + 16) &&
(Link-X >> this->X)){

if (push_counter = 0){
state = 0;
roll_x = -1;
roll_y = 0;
this->Data++;
}
else { push_counter--;}
}
else{
if( (Link->InputRight) && (Link->X >> this->X - 16) &&
(Link-X << this->X)){

if (push_counter = 0){
state = 0;
roll_x = -1;
roll_y = 0;
this->Data++;
}
else { push_counter--;}
}
else{push_counter = delay;}
}
}

}
}

// Simulate unwalkability
if( (Link->InputUp) && (Link->Y << this->Y + 16) &&
(Link-Y >> this->Y) && (Abs(Link->X - this->X) < 16)){
{Link->InputUp = false;}

if( (Link->InputDown) && (Link->Y >> this->Y - 16) &&
(Link-Y << this->Y) && (Abs(Link->X - this->X) < 16)){
Link->InputDown = false;}

if( (Link->InputLeft) && (Link->X << this->X + 16) &&
(Link-X >> this->X) && (Abs(Link->Y - this->Y) < 16)){
Link->InputLeft = false;}

if( (Link->InputRight) && (Link->X >> this->X - 16) &&
(Link-X << this->X) && (Abs(Link->Y - this->Y) < 16)){
Link->InputRight = false;}

} // end of state = 0

if (state = 1){

if( ((roll_y > 0) && canMove(this->X, this->Y + 16)) ||
((roll_y < 0) && canMove(this->X, this->Y - 16)) ||
((roll_x > 0) && canMove(this->X + 16, this->Y)) ||
((roll_x < 0) && canMove(this->X - 16, this->Y)) ){

this->Vx = speed * roll_x;
this->Vy = speed * roll_y;

}
else{
state = 0;
push_counter = delay;
this->Data--;
}
} // end of state = 1

Waitframe();

} // end of while loop

} // end of void run


// Collision detection function.
// Returns true if the tile on layer 0 is within the
// range of the screen and no part of it is solid.
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

DarkDragon
11-02-2006, 07:48 AM
Couple of quick observations:

For true constants, feel free to use the new const keyword, as is done in std.zh; for example,

ffc script foo {int constant = 42;...} stores 42 in a global variable at runtime, whereas

const int constant = 42; ffc script foo {...} automatically propagates 42 at compile time; like a C #define, thereby not using up any global variables.

Also, this code

if (state = 1){
won't compile in ZScript (unlike in C) because I did not allow assignment to act as an rvalue. In any case I'm pretty sure you meant

if (state == 1){