//v0.5.0 const int TEST_ETANKS = 1; float Samus[214747]; //Samus[] array indices const int ETANKS = 500; const int ETANKS_FULL = 501; const int ISDEAD = 214746; const int DEATH_Q = 214742; const int DEATH_RADIUS = 214744; const int DEATH_REFILLED = 214743; const int RUNNING_DEATH = 214745; const int HP_REFILL_RATE =30; const int SFX_ETANK_REFILL = 60; const int DEATH_WIPE_DUR = 120; //4 seconds const int MIDI_DEATH = 1; const int SFX_MET_DEATH = 20; int Etanks(){ return Samus[ETANKS]; } int ETanksFilled(){ return Samus[ETANKS_FULL]; } void FillETanks(){ Samus[ETANKS_FULL] = Samus[ETANKS]; } void UseEtank(){ Samus[ETANKS_FULL]--; } //Returns if Samus still hyas energy, refillng from etanks in the process, as needed. bool HasEnergy(){ if ( Link->HP <= 0 ){ if ( ETanksFilled() ) { Link->HP = Link->MaxHP; UseEtank(); return true; } return false; } else return true; } //Pickup script item script Etank{ void run(){ Samus[ETANKS]++; Samus[ETANKS_FULL]++; } } //Refills hp and etanks void RefillHealth(bool silent) { Link->HP = Link->MaxHP; do { if ( !silent ) Game->PlaySound(SFX_ETANK_REFILL); Samus[ETANKS_FULL]++; if ( !silent ) Waitframes(HP_REFILL_RATE); } while ( ETanksFilled() < Etanks() ); } void ShowETanks(){ if ( Link->MP != ETanksFilled() * 32 ) Link->MP = ETanksFilled() * 32; } int IsDead(){ return Samus[ISDEAD]; } void IsDead(bool state){ if (state) Samus[ISDEAD] = 1; else Samus[ISDEAD] = 0; } global script Init{ void run(){ IsDead(false); //Initialize counters. Game->MCounter[CR_ARROWS] = 0; Game->MCounter[CR_RUPEES] = 0; Game->MCounter[CR_SBOMBS] = 0; Game->MCounter[SECRET_COUNTER] = 100; Game->MCounter[METROID_HP_COUNTER] = 999; Game->Counter[HEALTH_COUNTER] = 99; SetCommonStyleData(WINDOW_STYLE_1); SetCommonStyleData(WINDOW_STYLE_2); SetCommonStyleData(WINDOW_STYLE_3); } } global script OnContinue{ void run() { IsDead(false); } } global script MetroidActive{ void run(){ IsDead(false); if ( TEST_ETANKS ) { Samus[ETANKS] = 2; Samus[ETANKS_FULL] = 2; } int PrevTanks = NumTanks;//Initialize variable to track tanks between frames. linkPrevHP = Link->HP;//Initialize variable. //Initialize this variable. //Used by Sideview Ladder Script int olddmap = Game->GetCurDMap(); int oldscreen = Game->GetCurDMapScreen(); Tango_Start(); StartGhostZH(); //Used by function in grapple. ForcePosX = -1000; ForcePosY = -1000; ResumeGame(); //Go to last saved position. while ( true ) { while( !IsDead () ){ Detect250_1_Phase1(); //Check to see if we are using 2.50.1... Detect250_1_Phase2(); //2.50.1 Checking confirmed to work at this point (v0.4.2) Detect250_2(); //Check for v2.50.2 ia Jumping mechanics. Version_Check_Cleanup(); if ( !HasEnergy() ){ Link->HP = Link->MaxHP; IsDead(true); break; } ShowETanks(); //Link has died. //GameOver(); //Probably not used any longer. //Game->Counter[METROID_HP_COUNTER]= MetroidCurrentHP; Game->Counter[METROID_HP_COUNTER]= MetroidCurrentHP; ScrollFix();//Fix scrolling animations. //Draw Samus. if( !Link->Invisible && !isMorphed && !IsDead() ) Draw_Samus(); if ( SamusAction != SAMUS_ACTION_CROUCH && !isMorphed ) Custom_Collision();//Run custom collision code. Weapon_Realignment();//Does weapon moving stuff WeaponGravityIgnorance();//Custom eweapon gravity interaction. Item_Gravity_Ignorance();//Does Item hovering. //Not having a game over. if ( Link->HP >= 2 ){ //Run energy tanks. //health(); //Varia suit compatibility. Hot_Room(); //HP Regen Item HP_Regeneration(); } UpdateGhostZH1(); //If you have the screw attack and this is a sideview scren. if ( Link->Item[I_SCREWATTACK] ){ if ( jumping && !isScrewAttack ) isScrewAttack = true; //Deactivate Screw Attack. else if ( !jumping && isScrewAttack ){ isScrewAttack = false; //Clear screw attack lweapon. RemoveLWeaponType(LW_SCREWATTACK); } } //You have more tanks than you did last frame. //if( NumTanks > PrevTanks ){ // PrevTanks = NumTanks;//Set variable to new value. // //Max health counter. // Game->Counter[HEALTH_COUNTER] = 99; // CurrentFilledTanks= NumTanks;//Match variable amount. // item TradeSeqItem; // //Create the item and place it at Link's location. // TradeSeqItem = Screen->CreateItem(I_MAGICCONTAINER); // TradeSeqItem->X = Link->X; // TradeSeqItem->Y = Link->Y; // TradeSeqItem->Pickup |= IP_HOLDUP; //} Tango_Update1(); Waitdraw(); if ( DEBUG_VERSION_FUNCTIONS && Link->PressEx2 ) { //If debugging is on and Link presses Ex2 TraceNL(); //Put some useful traces in allegro.log. Trace(Version[ZC_VERSION]); } //Safety net post-waitdraw call: if ( !HasEnergy() ){ Link->HP = Link->MaxHP; IsDead(true); break; } Tango_Update2(); //Run morph ball. MorphBall(); UpdateLWZH();//Does fancy Lweapon stuff. //Jump script. VariableJump(); //Run sideview slopes. UpdateStairCombos(); PushLinkOutOfSolidCombos(); //You're not morphed right now. if ( !isMorphed ){ //Handles sideview ladder between screens. VJumpLaddersGlobal(); //Lets you phase through one tile walls. Phase_Modulator(); //Allows you to grip some walls or all walls. Sideview_Grip(); //Speed boost. Speed_Boost(); //Run screw attack stuff. ScrewAttack(); } //Run blocks that crumble in sideview. if ( IsSideview() ) SideviewStep(); if ( VJumpVars[BEAM_FIRING_TIMER] > 0 ) VJumpVars[BEAM_FIRING_TIMER]--; else VJumpVars[BEAM_FIRING_TIMER] = 0; //Run this script, associated with grapple beam. ForcePos(); UpdateGhostZH2(); Prev_Link_Dir = Link->Dir;//Track direction Link is facing. Waitframe(); } while ( IsDead() ) { //display screen, or do wipe if ( !RunningDeath() ) Death(); //GAME OVER MENU Waitdraw(); Waitframe(); } Waitframe(); } } } void ResumeGame(){ ResumeGhostZHScripts(); RestoreGame(); } void Death() { RunningDeath(true); SuspendGhostZHScripts(); Samus[DEATH_RADIUS] = DEATH_WIPE_DUR; Link->HP = Link->MaxHP; InvertedCircle(1, 6, Link->X + 8, Link->Y, DEATH_WIPE_DUR, -1, 0x0F); WarpSamus( GetGameRestoreStation(), 0 ); Game->PlaySound(SFX_MET_DEATH); for ( Samus[DEATH_Q] = 0; Samus[DEATH_Q] < DEATH_WIPE_DUR; Samus[DEATH_Q] ++ ) { Link->HP = Link->MaxHP; InvertedCircle(4, 6, Link->X + 8, Link->Y, --Samus[DEATH_RADIUS], 100, 0x0F); if ( Game->GetMIDI() != MIDI_DEATH ) Game->PlayMIDI(MIDI_DEATH); Waitdraw(); WaitNoAction(); } for ( Samus[DEATH_Q] = 0; Samus[DEATH_Q] < DEATH_WIPE_DUR; Samus[DEATH_Q] ++ ) { if ( !Samus[DEATH_REFILLED] ) { RefillHealth(true); Samus[DEATH_REFILLED] = 1; if ( IsDead() ) IsDead(false); if ( RunningDeath() ) RunningDeath(false); } InvertedCircle(4, 6, Link->X + 8, Link->Y, ++Samus[DEATH_RADIUS], 100, 0x0F); Waitdraw(); WaitNoAction(); } ResumeGhostZHScripts(); } void RunningDeath(bool state){ if ( state ) Samus[RUNNING_DEATH] = 1; else Samus[RUNNING_DEATH] = 0; } int RunningDeath() { return Samus[RUNNING_DEATH]; }