PDA

View Full Version : Ice Pushblocks



Dan Furst
05-30-2007, 02:35 PM
This script allows you to make ice pushblock puzzles. You can have up to eight blocks on the screen and up to six ice block triggers. The ice blocks move in the direction pushed until they hit a solid combo, another ice block, or any combo with an inherent flag of "No Push Block" (#67). You have to make each "icy floor" combo a new combo, because I change the solidity of the floor. The script also uses as many D[] screen registers as ice blocks. When all of the ice triggers are satisfied, the script kills the first enemy, which should be a Trigger enemy.

Here's an example quest with some puzzles. (The cheat is "4" if you're no good. ;) ) I developed and tested under 311.

iceblock.qst (http://filer.case.edu/dpf4/iceblock.qst)

And the code. If you're going to use this script as-is, you HAVE to follow all of the instructions noted at the top. Make each ice block the first freeform combos in order. The next one combo should be the trigger. Each block must have it's ffc number passed in. The trigger combo must have it's ffc number, then the number of ice blocks on the screen, then the locations of each trigger. I've made a simple map of screen locations here (http://filer.case.edu/dpf4/screen_nums.bmp).


// The ice blocks must start at ffc #1 and then use 2, 3, etc.... You may have up to eight ice blocks.
// Each square of ice on the screen must be a new combo. These combos can be used only once each (in the entire quest).
// To have ice blocks stop sliding at the "edge" of ice, make the surrounding combos inherently "No Push Block" (flag 67).
// You must put the "Trigger" enemy on the screen, and it must be the first enemy listed.
// To have the door(s) always close upon room re-entry, check the "Enemies Always Return" screen rule.
// The "ice trigger" freeform combo should be any completely transparent tile (other than combo 0).
// Starting with the third argument (D2), pass in all of the locations you want triggers. Use them in order.
// Pass them in as the ith combo on the screen, starting with 0 as the top left. Combos are counted left to right, top to bottom.



import "std.zh"

ffc script ice_push{
void run(int this_ffc_num)
{
ffc this_ffc = Screen->LoadFFC(this_ffc_num);

// make the combos at the saved positions walkable
Screen->ComboS[(Screen->D[this_ffc_num-1])] = 0;

while(true)
{
//make where I am unwalkable
Screen->ComboS[this_ffc->Y + (this_ffc->X >> 4)] = 15; // 15d = 1111b

//if Link is trying to push it Right
if(Link->X == this_ffc->X - 16 && (Link->Y < this_ffc->Y + 1 && Link->Y > this_ffc->Y - 12) && Link->InputRight)
{
while(Screen->ComboI[this_ffc->Y + ((this_ffc->X + 16) >> 4)] != 67 && // not "No Push Block"
Screen->ComboS[this_ffc->Y + ((this_ffc->X + 16) >> 4)] == 0) // and is walkable
{
Screen->ComboS[this_ffc->Y + (this_ffc->X >> 4)] = 0;
this_ffc->Vx = 1;
for(int j=0; j<16; j++)
{
Link->Dir = DIR_RIGHT;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
Waitframe();
}
}
this_ffc->Vx = 0;
// save the position
Screen->D[this_ffc_num-1] = this_ffc->Y + (this_ffc->X >> 4);
Waitframe();
}
//if Link is trying to push it Left
else if(Link->X == this_ffc->X + 16 && (Link->Y < this_ffc->Y + 1 && Link->Y > this_ffc->Y - 12) && Link->InputLeft)
{
while(Screen->ComboI[this_ffc->Y + ((this_ffc->X - 16) >> 4)] != 67 && // not "No Push Block"
Screen->ComboS[this_ffc->Y + ((this_ffc->X - 16) >> 4)] == 0) // and is walkable
{
Screen->ComboS[this_ffc->Y + (this_ffc->X >> 4)] = 0;
this_ffc->Vx = -1;
for(int j=0; j<16; j++)
{
Link->Dir = DIR_LEFT;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
Waitframe();
}
}
this_ffc->Vx = 0;
// save the position
Screen->D[this_ffc_num-1] = this_ffc->Y + (this_ffc->X >> 4);
Waitframe();
}
//if Link is trying to push it Down
else if(Link->Y == this_ffc->Y - 16 && (Link->X < this_ffc->X + 4 && Link->X > this_ffc->X - 4) && Link->InputDown)
{
while(Screen->ComboI[(this_ffc->Y + 16) + (this_ffc->X >> 4)] != 67 && // not "No Push Block"
Screen->ComboS[(this_ffc->Y + 16) + (this_ffc->X >> 4)] == 0) // and is walkable
{
Screen->ComboS[this_ffc->Y + (this_ffc->X >> 4)] = 0;
this_ffc->Vy = 1;
for(int j=0; j<16; j++)
{
Link->Dir = DIR_DOWN;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
Waitframe();
}
}
this_ffc->Vy = 0;
// save the position
Screen->D[this_ffc_num-1] = this_ffc->Y + (this_ffc->X >> 4);
Waitframe();
}
//if Link is trying to push it Up
else if(Link->Y == this_ffc->Y + 8 && (Link->X < this_ffc->X + 4 && Link->X > this_ffc->X - 4) && Link->InputUp)
{
while(Screen->ComboI[(this_ffc->Y - 16) + (this_ffc->X >> 4)] != 67 && // not "No Push Block"
Screen->ComboS[(this_ffc->Y - 16) + (this_ffc->X >> 4)] == 0) // and is walkable
{
Screen->ComboS[this_ffc->Y + (this_ffc->X >> 4)] = 0;
this_ffc->Vy = -1;
for(int j=0; j<16; j++)
{
Link->Dir = DIR_UP;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
Waitframe();
}
}
this_ffc->Vy = 0;
// save the position
Screen->D[this_ffc_num-1] = this_ffc->Y + (this_ffc->X >> 4);
Waitframe();
}
else
{
Waitframe();
}
}
}
}//end



ffc script ice_trigger{
void run(int this_ffc_num, int num_of_ice_blocks, int loc_1, int loc_2, int loc_3, int loc_4, int loc_5, int loc_6)
{
ffc this_ffc = Screen->LoadFFC(this_ffc_num);

int x1;
int x2;
int x3;
int x4;
int x5;
int x6;
int y1;
int y2;
int y3;
int y4;
int y5;
int y6;
int num_triggers = 0;
int good_counter = 0;
bool once = true;

if(loc_1 != 0)
{
x1 = (loc_1 &#37; 16) * 16;
y1 = Floor(loc_1 / 16) * 16;
num_triggers++;

}
else
{
Quit();
}
if(loc_2 != 0)
{
x2 = (loc_2 % 16) * 16;
y2 = Floor(loc_2 / 16) * 16;
num_triggers++;
}
if(loc_3 != 0)
{
x3 = (loc_3 % 16) * 16;
y3 = Floor(loc_3 / 16) * 16;
num_triggers++;
}
if(loc_4 != 0)
{
x4 = (loc_4 % 16) * 16;
y4 = Floor(loc_4 / 16) * 16;
num_triggers++;
}
if(loc_5 != 0)
{
x5 = (loc_5 % 16) * 16;
y5 = Floor(loc_5 / 16) * 16;
num_triggers++;
}
if(loc_6 != 0)
{
x6 = (loc_6 % 16) * 16;
y6 = Floor(loc_6 / 16) * 16;
num_triggers++;
}

while(true)
{
for(int i=1; i<num_of_ice_blocks+1; i++)
{
ffc block_ffc = Screen->LoadFFC(i);

//if a block is on #1 and not moving
if(x1 == block_ffc->X && y1 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
if(x2 == block_ffc->X && y2 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
if(x3 == block_ffc->X && y3 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
if(x4 == block_ffc->X && y4 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
if(x5 == block_ffc->X && y5 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
if(x6 == block_ffc->X && y6 == block_ffc->Y && block_ffc->Vx == 0 && block_ffc->Vy == 0)
{
good_counter++;
}
}
if(good_counter == num_triggers && once == true)
{
once = false;
npc trigger = Screen->LoadNPC(1);
if(trigger->HP != 0)
{
trigger->HP = 0;
Game->PlaySound(SFX_SECRET);
}
}
good_counter = 0;
Waitframe();
}
}
}//end


So what do you think?

Majora
06-08-2007, 06:06 PM
ZQuest Crashes when I try to open the quest in 254 :(

Dan Furst
06-08-2007, 11:31 PM
Cuz 254 is old and grey. Use 311 or later. (www.shardstorm.com)

Rastael
12-06-2010, 11:45 AM
I can compile the script, but the push-blocks-ffcs doesn't do anything.
They are not even solid.
What do I wrong?