Copy to Clipboard Test

Doom Laser Code

const int SFX_DOOMLASER = 32; //Sound to play, when laser fires.
const int SFX_DOOMLASER_OPTICS = 6; //Sound to play when laser hits optics combo.
const int SFX_INSTANTDEATH = 14; //Sound to play, when Link gets fried by laser. Unfortunately it does not play due to warp sheinanigans.

const int SPR_LASER_OPTICS = 89;//Sprite used when optics combo tries to withstand disintegrating power of deadly laser.

//Requires ghost.zh

//Doom laser, invented by Quickman. It takes time to fire and travel and can be obscured by solid combos. 
//But one touch - and Link will be ISTANTLY DISINTEGRATED, no sell!!! Technically he will be warped to dungeon entrance with +1 to death count. if D4 is set to 0. 
//Place FFC where laser starts.
//D0 - Delay between script init and laser firing, in frames.
//D1 - Laser direction.
//D2 - Tile used to draw laser, 1 frame stretched.
//D3 - Laser travel speed, in pixels per frame. Default is 2.
//D4 - Damage. Cheap Chiniese materials!

ffc script DoomLaser{
	void run(int delay, int dir, int tile, int speed, int damage){
		if (speed==0)speed=2;
		int rtgx = this->X+15;
		int rtgy = this->Y+15;
		while (true){			
			if (delay>0)delay--;
			else {
				if (delay==0){
					Game->PlaySound(SFX_DOOMLASER);
					delay--;
				}
				if (dir==DIR_UP){
					this->Y-=speed;
					if (speed>0){
						if (LaserHitOptics(this, this->X, this->Y, this->InitD[3], dir, damage, tile)){
							int cmb = ComboAt(this->X, this->Y);
							eweapon e = Screen->CreateEWeapon(EW_SCRIPT10);
							e->X = ComboX(cmb);
							e->Y = ComboY(cmb);
							e->Damage = damage;
							if (damage==0) e->Damage = 65536;
							e->UseSprite(SPR_LASER_OPTICS);
							e->DeadState = -1;
							e->HitXOffset++;
							e->HitYOffset++;
							e->HitWidth-=2;
							e->HitHeight=-2;
							e->Behind=false;
							Game->PlaySound(SFX_DOOMLASER_OPTICS);
							speed=0;
						}
						else if (Screen->isSolid(this->X , this->Y)){
							this->Y+=speed;
							speed=0;
						} 
					}					
				}
				if (dir==DIR_DOWN){
					rtgy+=speed;
					if (speed>0){
						if (LaserHitOptics(this, this->X, rtgy, this->InitD[3], dir, damage, tile)){
							int cmb = ComboAt(this->X, rtgy);
							eweapon e = Screen->CreateEWeapon(EW_SCRIPT10);
							e->X = ComboX(cmb);
							e->Y = ComboY(cmb);
							e->Damage = damage;
							if (damage==0) e->Damage = 65536;
							e->UseSprite(SPR_LASER_OPTICS);
							e->DeadState = -1;
							e->HitXOffset++;
							e->HitYOffset++;
							e->HitWidth-=2;
							e->HitHeight=-2;
							Game->PlaySound(SFX_DOOMLASER_OPTICS);
							speed=0;
						}
						else if (Screen->isSolid(rtgx , rtgy)){
							rtgy-=speed;
							speed=0;
						}  
					}
					
				}
				if (dir==DIR_LEFT){
					this->X-=speed;
					if (speed>0){
						if (LaserHitOptics(this, this->X, this->Y, this->InitD[3], dir, damage, tile)){
							int cmb = ComboAt(this->X, this->Y);
							eweapon e = Screen->CreateEWeapon(EW_SCRIPT10);
							e->X = ComboX(cmb);
							e->Y = ComboY(cmb);
							e->Damage = damage;
							if (damage==0) e->Damage = 65536;
							e->UseSprite(SPR_LASER_OPTICS);
							e->DeadState = -1;
							e->HitXOffset++;
							e->HitYOffset++;
							e->HitWidth-=2;
							e->HitHeight=-2;
							Game->PlaySound(SFX_DOOMLASER_OPTICS);
							speed=0;
						}
						else if (Screen->isSolid(this->X , this->Y)){
							this->X+=speed;
							speed=0;
						} 
					}					
				}
				if (dir==DIR_RIGHT){
					rtgx+=speed;
					if (speed>0){
						if (LaserHitOptics(this, rtgx, this->Y, this->InitD[3], dir, damage, tile)){
							int cmb = ComboAt(rtgx, this->Y);
							eweapon e = Screen->CreateEWeapon(EW_SCRIPT10);
							e->X = ComboX(cmb);
							e->Y = ComboY(cmb);
							e->Damage = damage;
							if (damage==0) e->Damage = 65536;
							e->UseSprite(SPR_LASER_OPTICS);
							e->DeadState = -1;
							e->HitXOffset++;
							e->HitYOffset++;
							e->HitWidth-=2;
							e->HitHeight=-2;
							Game->PlaySound(SFX_DOOMLASER_OPTICS);
							speed=0;
						}
						else if (Screen->isSolid(rtgx , rtgy)){
							rtgx-=speed;
							speed=0;
						} 
					}					
				}
				Screen->DrawTile(2, this->X, this->Y, tile, 1, 1, this->CSet, Abs(rtgx-this->X), Abs(rtgy - this->Y), 0, 0, 0, 0, false, OP_OPAQUE);
				if (RectCollision(Link->X, Link->Y, Link->X+15, Link->Y+15, this->X, this->Y, rtgx, rtgy)){
					if (damage==0){
						Game->PlaySound(SFX_INSTANTDEATH);
						Screen->Rectangle(7, 0, 0, 256, 176, 0x93, -1, 0, 0, 0, true, OP_OPAQUE);
						Waitframe();
						int retdmap = Game->LastEntranceDMap;
						int retscreen = Game->LastEntranceScreen;
						Link->Warp(retdmap, retscreen);
						Game->NumDeaths++;
					}
					else{
						eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, damage, -1, -1, EWF_UNBLOCKABLE);
						e->Dir = Link->Dir;
						e->DrawYOffset = -1000;
						SetEWeaponLifespan(e, EWL_TIMER, 1);
						SetEWeaponDeathEffect(e, EWD_VANISH, 0);
					}
				}
			}
			Waitframe();
		}
	}
}

bool LaserHitOptics(ffc this, int x, int y,int speed, int dir, int damage, int tile){
	if (dir==DIR_UP){
		int cmb = ComboAt(x,y);
		if (Screen->ComboT[cmb]==CT_MIRRORSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MIRRORBACKSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM4WAY){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile);
			return true;
		}
		return false;
	}
	if (dir==DIR_DOWN){
		int cmb = ComboAt(x,y);
		if (Screen->ComboT[cmb]==CT_MIRRORSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MIRRORBACKSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM4WAY){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile-1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile);
			return true;
		}
		return false;
	}
	if (dir==DIR_LEFT){
		int cmb = ComboAt(x,y);
		if (Screen->ComboT[cmb]==CT_MIRRORSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MIRRORBACKSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM4WAY){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_LEFT, damage, tile);
			return true;
		}
		return false;
	}
	if (dir==DIR_RIGHT){
		int cmb = ComboAt(x,y);
		if (Screen->ComboT[cmb]==CT_MIRRORSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MIRRORBACKSLASH){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			return true;
		}
		if (Screen->ComboT[cmb]==CT_MAGICPRISM4WAY){
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_UP, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_DOWN, damage, tile+1);
			FireDoomLaser( this, ComboX(cmb), ComboY(cmb), speed, DIR_RIGHT, damage, tile);
			return true;
		}
		return false;
	}
}

void FireDoomLaser(ffc n, int x, int y, int speed, int dir, int damage, int tile){
	int str[] = "DoomLaser";
	int scr = Game->GetFFCScript(str);
	int args[] = {0, dir, tile, speed, damage};
	int fffc = RunFFCScript(scr, args);
	if (fffc>0){
		ffc f = Screen->LoadFFC(fffc);
		f->X=x;
		f->Y=y;
		f->CSet = n->CSet;
	}
}