const int SFX_LINK_DEATH_SCREAM = 69; //Link`s scream SFX. //-- //death.zh A library for making alternate death animations for Link. // //Requires ghost.zh //Import and compile the library. Assign FFC script slots for death sequence scripts and test scripts. //In subscreen editor, edit HP gauge, so "1 HP" tile looks like "0 HP/empty". // //A note for scripting custom death animations. Instead of Waitframe, use WaitNoAction to prevent escapes offscreen. //Also make sure Link is not moved by anything, like sideview gravity, again to prevent escapes. //Always end those scripts with Link->HP=0; to kill Link for real. //Main function that deals damage to Link and executes alternate death animation, if it drives Link`s HP to <= 0. //Damage - damage //Deathtype - FFC script slot number //args - pointer for array, containing arguments for script //scream - play SFX_LINK_DEATH_SCREAM sound in additional to and sounds played by script. void AltDamageLink(int damage, int deathtype, int args, bool scream ){ if (Link->HP<=1) return; if (Link->HP<=damage && deathtype>0){ if (scream)Game->PlaySound(SFX_LINK_DEATH_SCREAM); Link->HP=1; ffc death = RunFFCScriptOrQuit(deathtype, args); death->X=Link->X; death->Y=Link->Y; Game->PlayMIDI(0); } 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); } } //Link gets cut in half. Blades, chompers, lasers etc. //D0 - 0-sliced horizontally, 1-sliced vertically //D1 - sprite for left/top half //D2 - sprite for bottom/right half //D3 - part flight speed //D4 - sound to play at the start of horror //D5 - total duration of sequence, in frames. //D6 - >0 - Link`s remnants are affected by sideview gravity. ffc script LinkDeathCutInHalf{ void run (int dir, int tile1, int tile2, int speed, int sound, int duration, int grav){ Game->PlaySound(sound); lweapon l1 = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y); lweapon l2 = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y); Link->Invisible=true; l1->UseSprite(tile1); l2->UseSprite(tile2); l1->CollDetection=false; l2->CollDetection=false; l1->DeadState=duration; l2->DeadState=duration; int l1x = l1->X; int l1y = l1->Y; int l2x = l2->X; int l2y = l2->Y; if (IsSideview()&& grav>0){ int dir1=Rand(45)+90; int dir2=Rand(45)+45; int lv1=Sin(dir1)*-speed; int lv2=Sin(dir2)*-speed; for (int i =0;i<duration;i++){ //speed+=0.05; if (l1->isValid()){ l1x-=speed; l1->X=l1x; lv1=Min(TERMINAL_VELOCITY, lv1+GRAVITY); l1y+=lv1; l1->Y=l1y; } if (l2->isValid()){ l2x+=speed; l2->X=l2x; lv2=Min(TERMINAL_VELOCITY, lv2+GRAVITY); l2y+=lv2; l2->Y=l2y; } Link->Jump=0; WaitNoAction(); } } else{ for (int i =0;i<duration;i++){ if (dir==0){ l1x-=speed; l2x+=speed; l1->X=l1x; l2->X=l2x; } else{ l1y-=speed; l2y+=speed; l1->Y=l1y; l2->Y=l2y; } Link->Jump=0; WaitNoAction(); } } Link->HP=0; } } //Link gets blasted into stuff. Explosives, curses etc. //D0 - Blast size: 0-normal, 1-super //D1 - Sprite used for remnants //D2 - Remnant splatter area, in tiles //D3 - total duration of sequence, in frames. ffc script LinkDeathExplosion{ void run (int size, int splash, int splashsize, int duration){ Game->PlaySound(3); Link->Invisible=true; lweapon l; if (size>0)l=CreateLWeaponAt(LW_SBOMBBLAST, Link->X, Link->Y); else l=CreateLWeaponAt(LW_BOMBBLAST, Link->X, Link->Y); l->CollDetection=false; lweapon s=CreateLWeaponAt(LW_SCRIPT10, Link->X-splashsize*8+8, Link->Y-splashsize*8+8); s->UseSprite(splash); s->DeadState=duration; s->Extend=3; s->CollDetection=false; s->TileWidth=splashsize; s->TileHeight = splashsize; for (int i =0;i<duration;i++){ Link->Jump=0; WaitNoAction(); } Link->HP=0; } } //Burnt to nothing by hell fire. Anything fire-based //D0 - delay between spawning flames, in frames. //D1 - total duration of sequence, in frames. ffc script LinkDeathFire{ void run(int rate, int duration){ for (int i =duration;i>0;i--){ if (i>duration/3 && i%3==0){ Game->PlaySound(SFX_FIRE); lweapon s=CreateLWeaponAt(LW_FIRE, Link->X-8+Rand(16), Link->Y-8+Rand(16)); s->CollDetection=false; } Link->Invisible=true; Link->Jump=0; WaitNoAction(); } Link->HP=0; } } //Generic Link death animation. Frozen, Petrified, impaled etc. //D0 - Sprite used for remnants //D1 - sound to play at the start of horror //D2 - Remnant splatter area, in tiles //D3 - >0 - Link`s remnants are affected by sideview gravity. //D4 - total duration of sequence, in frames. //D5 - initial upwards velocity ffc script LinkDeathGeneric{ void run(int sprite, int sound, int splashsize, int grav, int duration, int vel){ Game->PlaySound(sound); Link->Invisible=true; lweapon s=CreateLWeaponAt(LW_SCRIPT10, Link->X-splashsize*8+8, Link->Y-splashsize*8+8); s->UseSprite(sprite); s->DeadState=duration; s->CollDetection=false; s->Extend=3; s->TileWidth=splashsize; s->TileHeight = splashsize; int ly=s->Y; vel*=-1; if (!IsSideview())vel=0; for (int i =0;i<duration;i++){ if (grav>0 && IsSideview()){ vel=Min(TERMINAL_VELOCITY, vel+GRAVITY); ly = s->Y+vel; s->Y=ly; } Link->Jump=0; WaitNoAction(); } Link->HP=0; } } //Guillotine - cuts in half, if touched, when it has positive Vy //D0 - death animation script slot //D1 - Sprite for left remnant //D2 - sprite for right remnant //D3 - sound on slice ffc script Guillotine{ void run(int scr, int spr1, int spr2, int sfx){ while(true){ if (LinkCollision(this) && this->Vy>0){ int args[]={1, spr1,spr2,2,sfx,128,1}; AltDamageLink(10000, scr, args, false); } Waitframe(); } } } //crusher - Reduces one into nothing but bloody smear on actual stomp, or performs one funny death animation //D0 - script alot for crushing death //D1 - remnant sprite size //D2 - remnant sprite slot //D3 - crush sound //D4 - script slot for alternate death //D5 - sprite slot for alternate death //D6 - sound for alternate death ffc script Crusher{ void run(int scr, int spr,int sprsize, int sfx,int altscr, int altspr, int altsfx){ while(true){ if (LinkCollision(this) && this->Vy>0 && Link->Y>(this->Y+this->EffectHeight-8)){ int args[]={spr, sfx,sprsize,0,128,0}; AltDamageLink(10000, scr, args, true); } else if (LinkCollision(this)){ int args[]={altspr, altsfx,1,1,180,4}; AltDamageLink(10000,altscr , args, false); } Waitframe(); } } } //Laser - cuts into pieces on touch //D0 - death animation script slot //D1 - remnant sprite slot //D2 - sound on death //D3 - remnant sprite size ffc script RE_Laser{ void run(int scr, int spr, int sfx, int sprsize){ while(true){ if (RectCollision(Link->X+7, Link->Y+7, Link->X+12, Link->Y+12, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){ int args[]={spr, sfx,sprsize,0,128,0}; AltDamageLink(10000, scr, args, true); } Waitframe(); } } } //Laser slices in half vertically on touch. //D0 - script alot for crushing death //D1 - Sprite for left remnant //D2 - sprite for right remnant //D3 - sound on slice ffc script RE_Laser2{ void run(int scr,int spr1,int spr2, int sfx){ while(true){ if (RectCollision(Link->X+7, Link->Y+7, Link->X+12, Link->Y+12, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){ int args[]={1, spr1,spr2,0.5,sfx,128,1}; AltDamageLink(10000, scr, args, true); } Waitframe(); } } } //Laser slices in half horizontally on touch. //D0 - script alot for crushing death //D1 - Sprite for left remnant //D2 - sprite for right remnant //D3 - sound on slice ffc script RE_LaserHoriz{ void run(int scr, int spr1, int spr2, int sfx){ while(true){ if (RectCollision(Link->X+7, Link->Y+7, Link->X+12, Link->Y+12, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){ int args[]={0, spr1,spr2,0.5,sfx,128,1}; AltDamageLink(10000, scr, args, true); } Waitframe(); } } } //Megaman x Castlevania spikes. Explode into ridiclous gibs on tough. //D0 - death animation script slot //D1 - remnant sprite slot //D2 - remnant sprite size ffc script KillerSpikes{ void run(int scr, int spr, int sprsize){ while(true){ if (RectCollision(Link->X+7, Link->Y+7, Link->X+12, Link->Y+12, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){ int args[]={1, spr,sprsize,128}; AltDamageLink(10000, scr, args, true); } Waitframe(); } } } //Lava - incenerates on touch //D0 - fiery death animation script slot ffc script KillerLava{ void run(int scr){ while(true){ if (RectCollision(Link->X+7, Link->Y+7, Link->X+12, Link->Y+12, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){ int args[]={4, 128}; AltDamageLink(10000, scr, args, true); } Waitframe(); } } }