const int SFX_Z2_BLOCK_HIT_GROUND = 3;//Sound to play when falling block hits ground.
const int SFX_Z2_BLOCK_FALL = 38;//Sound to play, when balling block spawns.
const int SPR_Z2_BLOCK_HIT_GROUND = 0;//Sprite to display, when falling block hits ground.
const int Z2_BLOCK_HIT_GROUND_QUAKE = 0;//Power of quake caused by falling block.
const int Z2_BLOCK_HITBOX_MARGIN = 1;//Hitbox margin for falling blocks.
//Z2 falling/stacking blocks.
//Solid blocks falling from ceiling/landsliding from top and stacking. Very dangerous, can crush Link for massive damage.
//Requires ghost.zh, LinkMovement.zh, SolidFFCs.zh
//1. Combine dependency global script functions, as shown in global script example.
//2. Import and compile the script. 2 FFC scripts and Global script to be assigned.
//3. Place invisible FFC at top left corner of landslide area. Assign "Z2BlockSpawner" FFC script to it.
// Data - Combo used by falling/stacked blocks.
// CSet - CSet used by falling/stacked blocks.
// D0 - Lanslide width, in combos/tiles.
// D1 - Damage by being hit by falling block in midair, in 1/4th of heart. Crushing damage is handled separately by SolidFFCs.zh
// D2 - Delay between block spawns, in frames.
// D3 - Combo flag to be assigned to combo on stack.
// D4 - >0 Stacked blocks fall, if left midair.
ffc script Z2BlockSpawner{
void run(int width, int dam, int cooldown, int flag, int recurrentfall){
int str[]="Z2_falling_block";
int scr = Game->GetFFCScript(str);
int timer = cooldown;
int stackx = 0;
while(true){
timer--;
if (timer<=0){
stackx = this->X+Rand(width)*16;
if (CanWalk(stackx, this->Y, DIR_DOWN, 1, true)){
int args[4]={GRAVITY,TERMINAL_VELOCITY,dam,flag};
ffc f = RunFFCScriptOrQuit(scr,args);
f->X = stackx;
f->Y = this->Y;
f->Data = this->Data;
f->CSet = this->CSet;
f->EffectWidth=16;
f->EffectHeight=16;
f->TileWidth=1;
f->TileHeight=1;
f->Vx=0;
f->Vy=0;
Game->PlaySound(SFX_Z2_BLOCK_FALL);
}
timer = cooldown;
}
for (int i=0;i<160;i++){
if (recurrentfall==0)break;
if (Screen->ComboD[i]!=this->Data)continue;
if (Screen->ComboS[i+16]>0) continue;
Screen->ComboD[i]=Screen->UnderCombo;
Screen->ComboC[i]=Screen->UnderCSet;
int args[4]={GRAVITY,TERMINAL_VELOCITY,dam,flag};
ffc f = RunFFCScriptOrQuit(scr,args);
f->X = ComboX(i);
f->Y = ComboY(i);
f->Data = this->Data;
f->CSet = this->CSet;
f->EffectWidth=16;
f->EffectHeight=16;
f->TileWidth=1;
f->TileHeight=1;
f->Vx=0;
f->Vy=0;
}
Waitframe();
}
}
}
ffc script Z2_falling_block{
void run(int grav, int term, int dam, int flag){
while(true){
this->Vy = Min(term, this->Vy+grav);
if ((RectCollision(Link->X, Link->Y, Link->X+15, Link->Y+Cond(IsSideview(),16,8), this->X+Z2_BLOCK_HITBOX_MARGIN, this->Y+Z2_BLOCK_HITBOX_MARGIN, this->X+15-Z2_BLOCK_HITBOX_MARGIN*2, this->Y+15-Z2_BLOCK_HITBOX_MARGIN*2))){
eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, dam, -1, -1, EWF_UNBLOCKABLE);
e->Dir = Link->Dir;
e->DrawYOffset = -1000;
SetEWeaponLifespan(e, EWL_TIMER, 1);
SetEWeaponDeathEffect(e, EWD_VANISH, 0);
}
if (!CanWalk(this->X, this->Y, DIR_DOWN, this->Vy, true)){
int cmb = ComboAt(CenterX(this),CenterY(this));
Screen->ComboD[cmb]=this->Data;
Screen->ComboC[cmb]=this->CSet;
Screen->ComboF[cmb]=flag;
Game->PlaySound(SFX_Z2_BLOCK_HIT_GROUND);
if (SPR_Z2_BLOCK_HIT_GROUND>0){
lweapon s = CreateLWeaponAt(LW_SPARKLE, this->X, this->Y);
s->UseSprite(SPR_Z2_BLOCK_HIT_GROUND);
s->CollDetection=false;
}
Screen->Quake = Z2_BLOCK_HIT_GROUND_QUAKE;
this->Data=0;
this->Vx=0;
this->Vy=0;
Quit();
}
if (this->Y>176){
this->Data=0;
this->Vx=0;
this->Vy=0;
this->Y=0;
this->Y=0;
Quit();
}
SolidObjects_Add(FFCNum(this), this->X, this->Y, 16, 16, this->Vx, this->Vy, 2);
Waitframe();
}
}
}
global script FallBlockActive{
void run(){
StartGhostZH();
Tango_Start();
__classic_zh_InitScreenUpdating();
LinkMovement_Init();
SolidObjects_Init();
while(true) {
SolidObjects_Update1();
LinkMovement_Update1();
UpdateGhostZH1();
__classic_zh_UpdateScreenChange1();
Tango_Update1();
__classic_zh_do_z2_lantern();
if ( __classic_zc_internal[__classic_zh_SCREENCHANGED] )
{
__classic_zh_CompassBeep();
__classic_zh_ResetScreenChange();
}
Waitdraw();
SolidObjects_Update2();
LinkMovement_Update2();
UpdateGhostZH2();
Tango_Update2();
Waitframe();
}
}
}