import "std.zh" ///////////////////////////////////////////////// //Import mandatory script headers and packages.// ///////////////////////////////////////////////// import "ffcscript.zh" import "string.zh" import "ghost.zh" import "ghost_legacy.zh" import "std_extra.zh" ///////////////////////////////////////////////////////////////////// // Set up environment, Base Ints, Consts, Floats, Bools, Vars, etc.// // Set Sounds in Quest->Audio->SFX Data //////////////////////////// ///////////////////////////////////////////////////////////////////// const int SFX_ERROR = 61; //In case you want an error SFX const int SFX_GUN = 71; //Set to a bang SFX as desired. const int SFX_RELOAD = 72; //Set to a bang SFX as desired. const int LW_MISC_TIMEOUT = 7; //================================================================== // ==== * INSTRUCTIONS * ==== //All items: Set their IDs in the I_ constants //Sound effects: Set the sounds in the SFX_ constants (0 disables the sound) //Settings: Read the descriptions of the EXP_ constants before editing //Treasure Hunter: Set the screen flag "General Purpose 1" on screens with chests //Meter: Read the descriptions of the EXP_METER_ constants before editing //=================================================================== const int I_FASTWALK = 17; //ID of the fast walk item const int I_LEADERSHIP = 17; //ID of the leadership item const int I_TREASUREHUNTER = 17; //ID of the treasure hunter item const int CR_EXP = 30; //Counters for EXP and level (default 3 & 4) const int CR_LEVEL = 31; const int SFX_LEVEL = 32; //SFX to play when you level up (0 = disable) const int SFX_TREASURESCREEN = 27; //SFX to play when Treasure Hunter activates const int EXP_HP_RATIO = 1; //Enemy EXP value = HP divided by this const int EXP_PER_LEVEL = 999999; //Amount of EXP to level up const int EXP_MAX_LEVEL = 20; //Highest possible level const int EXP_LEADERSHIPCHANCE = 10; //One in {this} chance to get +1 exp const int EXP_FASTWALKRATE = 5; //Every {this} frames, walk an extra pixel const int EXP_METER_X = 50; //Starting coordinates of the EXP meter const int EXP_METER_Y = -8; //Subscreen Y values are < 0; need to play around with this const int EXP_METER_WIDTH = 8; //How wide the meter is const int EXP_METER_LENGTH = 64; //How long the meter can get const int EXP_METER_COLOR = 1; //Color = (CSet# * 16) + color within CSet from 0 to 15 const int SF_TREASURE = 0; //Which screen flag to check for treasure (default Script1) const int HP_DEAD = -999; //Enemy has been counted for EXP (don't touch) const int NPC_MISC_MAXHP = 0; //Which npc->Misc[] value to store HP in (don't touch) global script active{ void run(){ int fastWalkTimer; int lastScreen = Game->GetCurDMapScreen(); int lastDMap = Game->GetCurDMap(); while(true){ //Weapon checks for ( int i = Screen->NumLWeapons(); i > 0; i-- ) { lweapon weap = Screen->LoadLWeapon(i); weap->DeadState = WDS_ALIVE; //Timeout if ( weap->Misc[LW_MISC_TIMEOUT] > 0 ){ weap->Misc[LW_MISC_TIMEOUT]--; if ( weap->Misc[LW_MISC_TIMEOUT] <= 0 ) weap->DeadState = WDS_DEAD; } } //Exp gain and level up if ( Game->Counter[CR_LEVEL] < EXP_MAX_LEVEL ){ //Disable if level is maxed setMaxHP(); checkEnemiesKilled(); } //Fast walk if ( Link->Item[I_FASTWALK] ){ fastWalkTimer++; fastWalkTimer %= EXP_FASTWALKRATE; if ( fastWalkTimer == 0 ) fastWalk(1); } //Treasure Hunter if ( Link->Item[I_TREASUREHUNTER] //If skill learned && (lastScreen != Game->GetCurDMapScreen() || lastDMap != Game->GetCurDMap()) //If new screen && checkScreenFlag(SF_TREASURE) //And flag active && !Screen->State[ST_ITEM] //And item not taken && !Screen->State[ST_CHEST] && !Screen->State[ST_LOCKEDCHEST] && !Screen->State[ST_BOSSCHEST] ){ Game->PlaySound(SFX_TREASURESCREEN); //Play SFX } lastScreen = Game->GetCurDMapScreen(); //Update last screen/DMap lastDMap = Game->GetCurDMap(); UpdateEWeapons(); CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0 Waitdraw(); AutoGhost(); DrawGhostFFCs(); Waitframe(); } } } //Check for new enemies and set their max HP void setMaxHP(){ for ( int i = Screen->NumNPCs(); i > 0; i-- ){ npc enem = Screen->LoadNPC(i); if ( enem->Misc[NPC_MISC_MAXHP] == 0 ) enem->Misc[NPC_MISC_MAXHP] = enem->HP; } } void checkEnemiesKilled(){ for ( int i = Screen->NumNPCs(); i > 0; i-- ){ npc enem = Screen->LoadNPC(i); if ( enem->HP <= 0 && enem->HP > HP_DEAD ){ enem->HP = HP_DEAD; int worth = enemyEXPWorth(enem); //Leadership: Chance to increase EXP worth if ( Link->Item[I_LEADERSHIP] && Rand(EXP_LEADERSHIPCHANCE) == 0 ) worth++; giveEXP(worth); } } } void expMeter(){ int length = EXP_METER_LENGTH * Game->Counter[CR_EXP] / EXP_PER_LEVEL; Screen->Rectangle(7, EXP_METER_X, EXP_METER_Y, EXP_METER_X + length, EXP_METER_Y + EXP_METER_WIDTH, EXP_METER_COLOR, 1, 0, 0, 0, true, OP_OPAQUE); } int enemyEXPWorth(npc enem){ return Max(1, enem->Misc[NPC_MISC_MAXHP] / EXP_HP_RATIO); } void giveEXP(int amount){ //Give EXP Game->Counter[CR_EXP] += amount; //Enough EXP to level up if ( Game->Counter[CR_EXP] > EXP_PER_LEVEL ){ Game->Counter[CR_EXP] -= EXP_PER_LEVEL; Game->Counter[CR_LEVEL]++; Game->PlaySound(SFX_LEVEL); //Level 20: Super Quake if ( Game->Counter[CR_LEVEL] >= EXP_MAX_LEVEL ){ Link->Item[I_QUAKESCROLL2] = true; Game->Counter[CR_EXP] = 0; //Also reset EXP } //Level 18: Cross beams else if ( Game->Counter[CR_LEVEL] == 18 ){ Link->Item[I_CROSSSCROLL] = true; } //Level 15: Hurricane Spin else if ( Game->Counter[CR_LEVEL] == 15 ){ Link->Item[I_SPINSCROLL2] = true; } //Level 13: Treasure Hunter else if ( Game->Counter[CR_LEVEL] == 13 ){ Link->Item[I_TREASUREHUNTER] = true; } //Level 12: Peril Beam else if ( Game->Counter[CR_LEVEL] == 12 ){ Link->Item[I_PERILSCROLL] = true; } //Level 10: Leadership else if ( Game->Counter[CR_LEVEL] == 10 ){ Link->Item[I_LEADERSHIP] = true; } //Level 9: Quake Hammer else if ( Game->Counter[CR_LEVEL] == 9 ){ Link->Item[I_QUAKESCROLL1] = true; } //Level 6: Spin Attack else if ( Game->Counter[CR_LEVEL] == 6 ){ Link->Item[I_SPINSCROLL1] = true; } //Level 5: Fast Walk else if ( Game->Counter[CR_LEVEL] == 5 ){ Link->Item[I_FASTWALK] = true; } //Level 3: Slash else if ( Game->Counter[CR_LEVEL] == 3 ){ Game->Generic[GEN_CANSLASH] = 1; } } } //Makes Link walk faster in addition to normal walking speed void fastWalk ( int speed ){ //Up if( Link->InputUp && !Screen->isSolid(Link->X,Link->Y+6) //NW && !Screen->isSolid(Link->X+7,Link->Y+6) //N && !Screen->isSolid(Link->X+15,Link->Y+6) //NE ) Link->Y -= speed; //Down else if( Link->InputDown && !Screen->isSolid(Link->X,Link->Y+17) //SW && !Screen->isSolid(Link->X+7,Link->Y+17) //S && !Screen->isSolid(Link->X+15,Link->Y+17) //SE ) Link->Y += speed; //Left else if( Link->InputLeft && !Screen->isSolid(Link->X-2,Link->Y+8) //NW && !Screen->isSolid(Link->X-2,Link->Y+15) //SW ) Link->X -= speed; //Right else if( Link->InputRight && !Screen->isSolid(Link->X+17,Link->Y+8) //NE && !Screen->isSolid(Link->X+17,Link->Y+15) //SE ) Link->X += speed; } bool checkScreenFlag(int flag){ return Screen->Flags[SF_MISC] & (4<Graphics->Sprites->WeaponsMisc. /// /// D6: Counter for Amo Boxes for this weapon /// /// D7: Counter to use for this weapon. /// ///////////////////////////////////////////////////////////////////// item script Firearm{ void run(int ammo, int nouse, int ShotsPerLoad, int power, int speed, int SWsprite, int AmmoToLoad, int GunCounter){ if (Game->Counter[GunCounter] >= 1){ Game->Counter[GunCounter] -= ammo; Link->ItemJinx = nouse; lweapon subweapon; if(subweapon->X >= 1 && subweapon->X <= 254 && subweapon->Y >= 1 && subweapon->Y <= 160) { subweapon->DeadState = WDS_ALIVE; //update sprites when dead state is refreshed subweapon->UseSprite(SWsprite); if(subweapon->Dir == DIR_DOWN) { subweapon->Flip = 2; } if(subweapon->Dir == DIR_RIGHT) { subweapon->Tile += 1; } if(subweapon->Dir == DIR_LEFT) { subweapon->Tile += 1; subweapon->Flip = 1; } } Link->Action = LA_ATTACKING; Game->PlaySound(SFX_GUN); subweapon = NextToLink(LW_ARROW, 8); //Create in front of Link subweapon->UseSprite(SWsprite); //Graphics subweapon->Damage = power; //Damage subweapon->Step = speed; //Speed if(subweapon->isValid()) subweapon->DeadState=-1; { //set to alive if within screen boundaries } subweapon->DeadState = WDS_ALIVE;} if (Game->Counter[GunCounter] <=0 && Game->Counter[AmmoToLoad] >=1){ Game->Counter[AmmoToLoad] -= 1; Game->Counter[GunCounter] += ShotsPerLoad; Game->PlaySound(SFX_RELOAD); Link->ItemJinx = (nouse * 2); } else{ Game->PlaySound(SFX_ERROR); } } } ////////////////// /// Ammo Pickup //////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// /// D0: Set to Counter for Type of Amunition You are Using /// /// D1: Amount of Ammo Boxes to Gain /// /// D2: Minimum Aount to Increase CounterMax; suggest 1. /// //////////////////////////////////////////////////////////////////// item script AmmoPickup{ void run(int AmmoCounter, int amount, int increaseAmmoCount){ Game->Counter[AmmoCounter]+=amount; Game->MCounter[AmmoCounter]+=increaseAmmoCount; } } ////////////////// /// Ammo Pickup //////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// /// D0: Set to Counter for Type of Amunition You are Using /// /// D1: Set to Counter for Firearm Being Loaded. /// /// D2: Amount of Rounds to Give player on Loading. /// /// D3: Time before Link can use this item again. /// //////////////////////////////////////////////////////////////////// item script AmmoLoad{ void run(int AmmoCounter, int GunCounter, int GunAmount, int nouse){ if (Game->Counter[AmmoCounter] >= 1 && Game->Counter[GunCounter] <= 0){ Game->Counter[AmmoCounter] -= 1; Game->Counter[GunCounter]+=GunAmount; Link->ItemJinx = nouse; Game->PlaySound(SFX_RELOAD); } else{ Game->PlaySound(SFX_ERROR); } } } /////////////////////////////////// ///// Counters Reference ////////// /////////////////////////////////// /// CR_SCRIPT1 = 7; /// /// CR_SCRIPT2 = 8; /// /// CR_SCRIPT3 = 9; /// /// CR_SCRIPT4 = 10; /// /// CR_SCRIPT5 = 11; /// /// CR_SCRIPT6 = 12; /// /// CR_SCRIPT7 = 13; /// /// CR_SCRIPT8 = 14; /// /// CR_SCRIPT9 = 15; /// /// CR_SCRIPT10 = 16; /// /// CR_SCRIPT11 = 17; /// /// CR_SCRIPT12 = 18; /// /// CR_SCRIPT13 = 19; /// /// CR_SCRIPT14 = 20; /// /// CR_SCRIPT15 = 21; /// /// CR_SCRIPT16 = 22; /// /// CR_SCRIPT17 = 23; /// /// CR_SCRIPT18 = 24; /// /// CR_SCRIPT19 = 25; /// /// CR_SCRIPT20 = 26; /// /// CR_SCRIPT21 = 27; /// /// CR_SCRIPT22 = 28; /// /// CR_SCRIPT23 = 29; /// /// CR_SCRIPT24 = 30; /// /// CR_SCRIPT25 = 31; /// ///////////////////////////////////