Copy to Clipboard Test

Falling blocks for Top Down areas Code

const int SFX_TD_FALLING_BLOCK_HIT_GROUND = 3;//Sound to play when falling block hits ground.
const int SFX_TD_FALLING_BLOCK_FALL = 38;//Sound to play, when balling block spawns.
const int SFX_TD_FALLING_BLOCK_DISSOLVE = 13;//Sound to play, when balling block destroys combo on landing.

const int SPR_TD_FALLING_BLOCK_HIT_GROUND = 22;//Sprite to display, when falling block hits ground.

const int TD_FALLING_BLOCK_HIT_GROUND_QUAKE = 0;//Power of quake caused by falling block. 
const int TD_FALLING_BLOCK_HITBOX_MARGIN = 1;//Hitbox margin for falling blocks.

const int CF_TD_FALLING_BLOCK_IMMUNITY = 67;//Combos flagged with this flag cannot be targeted by by falling block.

const int CMB_TD_FALLING_BLOCK_SHADOW=995;//Combo used to render shadow for falling block.
const int CSET_TD_FALLING_BLOCK_SHADOW=7;//CSet used to render shadow for falling block.

//Z1 falling blocks.

//Solid blocks falling from ceiling. Very dangerous, can crush Link for massive damage and block path. 

//Requires ghost.zh, LinkMovement.zh, SolidFFCs.zh 
//1. Combine dependency global script functions, as shown in global script example.
//2. Setup combo and CSet for shadow to be rendered by falling blocks. 
//3. Import and compile the script. 2 FFC scripts and Global script to be assigned.
//4. 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 - falling blocks area width, in combos/tiles.
// D1 - falling blocks area height, in combos/tiles.
// D2 - Damage by being hit by falling block in midair, in 1/4th of heart. Crushing damage is handled separately by SolidFFCs.zh
// D3- Delay between block spawns, in frames.
// D4 - Combo flag to be assigned to combo on stack.
// D5 - falling block starting Z height.
// D6 - ID of combo to replace combos targeted by falling blocks. Defaults to FFC`s combo. Uses FFC`s CSet. If D6 matches screen`s undercombo, SFX_TD_FALLING_BLOCK_DISSOLVE sound will play on landing, instead of SFX_TD_FALLING_BLOCK_HIT_GROUND.

ffc script TopDownFallingBlocks{
	void run(int width, int height, int dam, int cooldown, int flag,  int zheight, int cmbreplace){
		int str[]="TD_falling_block";
		int scr = Game->GetFFCScript(str);
		if (cmbreplace==0)cmbreplace=this->Data;
		int timer = cooldown;
		int cmbx = -1;
		int cmby = -1;
		int cmb = 0;
		while(true){
			timer--;
			if (timer<=0){
				cmbx = this->X+Rand(width)*16;
				cmby = this->Y+Rand(height)*16;
				cmb = ComboAt(cmbx+1, cmby+1);
				if (!ComboFI(cmb, CF_TD_FALLING_BLOCK_IMMUNITY) && Screen->ComboD[cmb]!=cmbreplace){
					int args[7]={GRAVITY,TERMINAL_VELOCITY,dam,flag, zheight, cmbreplace};
					ffc f = RunFFCScriptOrQuit(scr,args);
					f->X = cmbx;
					f->Y = cmby;
					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_TD_FALLING_BLOCK_FALL);
				}
				timer = cooldown;
			}
			Waitframe();
		}
	}
}

ffc script TD_falling_block{
	void run(int grav, int term, int dam, int flag , int zheight,  int cmbreplace){
		int origy = this->Y;
		this->Y-=zheight;
		int Vz = 0;
		while(true){
			Vz = Min(term, Vz+grav);
			zheight-=Vz;
			this->Y=origy-zheight;
			Screen->FastCombo	(1, this->X, origy,	CMB_TD_FALLING_BLOCK_SHADOW, CSET_TD_FALLING_BLOCK_SHADOW,OP_TRANS);
			if (zheight<=0){
				this->Y=origy;
				int cmb = ComboAt(CenterX(this),CenterY(this));
				Screen->ComboD[cmb]=cmbreplace;
				Screen->ComboC[cmb]=this->CSet;
				Screen->ComboF[cmb]=flag;
				if (cmbreplace==Screen->UnderCombo)Game->PlaySound(SFX_TD_FALLING_BLOCK_DISSOLVE);
				else Game->PlaySound(SFX_TD_FALLING_BLOCK_HIT_GROUND);
				if (SPR_TD_FALLING_BLOCK_HIT_GROUND>0){
					lweapon s = CreateLWeaponAt(LW_SPARKLE, this->X, this->Y);
					s->UseSprite(SPR_TD_FALLING_BLOCK_HIT_GROUND);
					s->CollDetection=false;
				}
				if ((RectCollision(Link->X, Link->Y, Link->X+15, Link->Y+Cond(IsSideview(),16,8), this->X+TD_FALLING_BLOCK_HITBOX_MARGIN, this->Y+TD_FALLING_BLOCK_HITBOX_MARGIN, this->X+15-TD_FALLING_BLOCK_HITBOX_MARGIN*2, this->Y+15-TD_FALLING_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 (Screen->ComboS[cmb]>0)SolidObjects_Add(FFCNum(this), this->X, this->Y, 16, 16, 0, 0, 2);
				Screen->Quake = TD_FALLING_BLOCK_HIT_GROUND_QUAKE;
				this->Data=0;
				this->Vx=0;
				this->Vy=0;
				Quit();
			}
			
			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();
		}
	}
}