//////////////////////////////// //// RPG System for ZC ///////// //// v.0.29 ////////// /////////////////////////////////////////////////////////////////////////// /// Creator: ZoriaRPG ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /// ASSISTANCE BY: ////// CONTRIBUTORS: ////// TESTING: ////// /// anikom15 ////// MoscowModder ////// ////// /// Avataro ////// grayswandir ////// ////// /// Zecora ////// ////// ////// /// ////// ////// ////// /// ////// ////// ////// /////////////////////////////////////////////////////////////////////////// //////////////////// /// Base Imports /// //////////////////// import "std.zh" //import "stdExtra.zh" //Not a dependency at this time. //immport "sdtZoria.zh" //Not a dependency at this time. //import stdArguments.zh //Not a dependency at this time. //////////////////////////////////// /// GLobal Constants & Variables /// //////////////////////////////////// //////////////////////////////////// /// Main Constants and Variables /// //////////////////////////////////// const int HP_DEAD = -999; const int NPC_MISC_MAXHP = 0; //Which npc->Misc[] value to store HP in (don't touch) const int EXP_HP_RATIO = 1; //Enemy EXP value = HP divided by this const int CR_HP = 8; const int CR_MP = 9; const int CR_HP_MAX = 10; const int CR_MP_MAX = 11; /////////////////////////////////////// ///XP & Stats Constants & Variables /// /////////////////////////////////////// const int CR_XP = 12; const int CR_LEVEL = 13; const int CR_LVL = 13; const int CR_XP_10K = 14; const int CR_STAT_MUSC = 26; const int CR_STAT_BODY = 27; const int CR_STAT_MIND = 28; const int CR_STAT_MYST = 29; const int CR_STAT_INFL = 30; const int CR_STAT_LUCK = 31; const int L1String = 1; const int L2String = 1; const int L3String = 1; const int L4String = 1; const int L5String = 3; const int L6String = 1; const int L7String = 1; const int L8String = 1; const int L9String = 1; const int L10String = 1; const int L11String = 1; const int L12String = 1; const int L13String = 1; const int L14String = 1; const int L15String = 1; const int L16String = 1; const int L17String = 1; const int L18String = 1; const int L19String = 1; const int L20String = 1; const int levelSound = 253; int gainLevel; // Cooldown timers for each button. Button presses are cancelled // unless their cooldown timer is <= 0 int Cooldown_ATimer = -1; int Cooldown_BTimer = -1; ////////////////////////////////////////////// /// Wallet and Money Constants & Variables /// ////////////////////////////////////////////// const int NO_FREE_SPACE = 0; //Sets default 'You don;t have the space to carry this item' message. const int NO_SPACE_SFX = 0; //Sets SFX to play when trying to pick up an item that you can't carry. int walletSize = 50; //Sts default space within wallets. Can be changed later in game. int walletsOwned = 1; //Setsa initial number of wallets owned by player. int walletSpaceUsed = 0; //Sets initial amount of used wallet space. int pockets = 2; //Sets initial number of pockets player has. Can be changed with clothing upgrades. int pocketCapacity = 20; // Sets pocket capacity for loose items. int pocketSpaceUsed = 0; //Sets initial pocket space used by player. int totalWalletSpace; int baseWalletSpace; int totalPocketSpace; int totalPocketAndWalletSpace; const int CR_CUSTOM_WALLET_SIZE = 0; //const int CR_WALLETS = 0; //const int NO_FREE_SPACE = 0; int valueStored; int coinsize; //int totalWalletSpace = ( CR_WALLETSPACE * CR_WALLETS ) //int freeWalletSpace = Game->MCounter[CR_WALLETSPACE] - Game->Counter[CW_WALLETSPACE] const int CR_SIZE_COINS_CURRENCY = 0; const int CR_DSARI = 0; bool noFreeSpace = false; bool reduced; /////////////////////////////////////////////////////// /// Armour, Shield, and Sword Constants & Variables /// /////////////////////////////////////////////////////// const int SHIELD_LOST = 0; //Set message to display when losing a sheild. const int SWORD_LOST = 0; //Set message to display when losing a sword. const int ARMOUR_LOST = 0; //Set message to display when losing armour. bool hasShield; bool shieldMessage = true; bool hasSword; bool swordMessage = true; bool hasArmour; bool armourMessage = true; /////////////////////////// /// SKill Check Globals /// /////////////////////////// int loreSkill; int loreSuccess = 0; //////////////////// /// Item GLobals /// //////////////////// int LastItemUsed = 0; int MISC_LWEAPON_ITEM = 0; ///////////////////// /// GLobal Script /// ///////////////////// global script active{ void run(){ InitializeGhostZHData(); int whipCooldownTimer = 0; int LinkX = Link->X; int LinkY = Link->Y; int fastWalkTimer; int lastScreen = Game->GetCurDMapScreen(); int lastDMap = Game->GetCurDMap(); Game->MCounter[CR_LEVEL] = 20; Game->MCounter[CR_XP] = 211500; Game->Counter[CR_STAT_BODY] = 10; Game->MCounter[CR_STAT_BODY] = 100; Game->Counter[CR_STAT_MUSC] = 10; Game->MCounter[CR_STAT_MUSC] = 100; Game->Counter[CR_STAT_MIND] = 10; Game->MCounter[CR_STAT_MIND] = 100; Game->Counter[CR_STAT_MYST] = 10; Game->MCounter[CR_STAT_MYST] = 100; Game->Counter[CR_STAT_INFL] = 10; Game->MCounter[CR_STAT_INFL] = 100; Game->Counter[CR_STAT_LUCK] = 10; Game->MCounter[CR_STAT_LUCK] = 100; while (true) { Game->Counter[CR_HP] = Link->HP; Game->Counter[CR_MP] = Link->MP; Game->Counter[CR_HP_MAX] = Link->MaxHP; Game->Counter[CR_MP_MAX] = Link->MaxMP; baseWalletSpace = ( walletSize * walletsOwned ); totalWalletSpace = ( baseWalletSpace + Game->Counter[CR_CUSTOM_WALLET_SIZE] ); totalPocketSpace = ( pockets * pocketCapacity ); totalPocketAndWalletSpace = ( totalWalletSpace + totalPocketSpace ); if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] > 98 ) { Game->MCounter[CR_XP] = 9999; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] > 98 && Game->Counter[CR_XP] > 9999 ) { Game->Counter[CR_XP] = 9999 ; } UpdateEWeapons(); CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0 UpdateLWeapons(); UpdateLastItem(); if (Link->PressB) {LastItemUsed = GetEquipmentB();} if (Link->PressA) {LastItemUsed = GetEquipmentA();} storeValue(); whipTimer(); goggles(); Waitdraw(); MCP(); secretTiners(); ringTimers(); byrnaTimers(); bootsTimers(); Cooldown_Update(); bombados(); compareValue(); XP(); AutoGhost(); DrawGhostFFCs(); lastScreen = Game->GetCurDMapScreen(); //Update last screen/DMap lastDMap = Game->GetCurDMap(); Waitframe(); } } } //////////////////////// /// Global FUnctions /// //////////////////////// ////////////////////////////////// //// XP System Base Functions //// ////////////////////////////////// int enemyEXPWorth(npc enem){ return Max(1, enem->Misc[NPC_MISC_MAXHP] / EXP_HP_RATIO); } void giveEXP(int amount){ //Give EXP Game->Counter[CR_XP] += amount; } //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 XP() { setMaxHP(); checkEnemiesKilled(); tenThousandPlace(); levelSystem(); } ////Counters need to resetat each level. //XP caps out at L15, and counter rolls over.If XP_10K == 1 && XP == 5000 // is the same as if XP == 15000 //or use 2nd counter to 10K place. Every 10K points, increase XP_10K by 1 //and work code to operateon both counters. void tenThousandPlace() { if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 0 ) { Game->Counter[CR_XP] = 1; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 1 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 2 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 3 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 4 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 5 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 6 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 7 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 8 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 9 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 10 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 11 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 12 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 13 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 14 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 15 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 16 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 17 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 18 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 19 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 20 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] == 21 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } if ( Game->Counter[CR_XP] > 9999 && Game->Counter[CR_XP_10K] > 21 && Game->Counter[CR_XP_10K] < 99 ) { Game->Counter[CR_XP] = 0; Game->Counter[CR_XP_10K]++; } } void levelSystem() { if ( Game->Counter[CR_LVL] == 0 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 100 ){ Game->Counter[CR_LVL] = 1; Level1(); } } if ( Game->Counter[CR_LVL] == 1 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 150 ) { Game->Counter[CR_LVL] = 2; Level2(); } } if ( Game->Counter[CR_LVL] == 1 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 2; Level2(); } } if ( Game->Counter[CR_LVL] == 2 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 225 ) { Game->Counter[CR_LVL] = 3; Level3(); } } if ( Game->Counter[CR_LVL] == 2 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 3; Level3(); } } if ( Game->Counter[CR_LVL] == 3 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 338 ) { Game->Counter[CR_LVL] = 4; Level4(); } } if ( Game->Counter[CR_LVL] == 3 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 4; Level4(); } } if ( Game->Counter[CR_LVL] == 4 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 507 ) { Game->Counter[CR_LVL] = 5; Level5(); } } if ( Game->Counter[CR_LVL] == 4 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 5; Level5(); } } if ( Game->Counter[CR_LVL] == 5 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 760 ){ Game->Counter[CR_LVL] = 6; Level6(); } } if ( Game->Counter[CR_LVL] == 5 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 6; Level6(); } } if ( Game->Counter[CR_LVL] == 6 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 1140 ){ Game->Counter[CR_LVL] = 7; Level7(); } } if ( Game->Counter[CR_LVL] == 6 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 7; Level7(); } } if ( Game->Counter[CR_LVL] == 7 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 1710 ){ Game->Counter[CR_LVL] = 8; Level8(); } } if ( Game->Counter[CR_LVL] == 7 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 8; Level8(); } } if ( Game->Counter[CR_LVL] == 8 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 2565 ){ Game->Counter[CR_LVL] = 9; Level9(); } } if ( Game->Counter[CR_LVL] == 8 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 9; Level9(); } } if ( Game->Counter[CR_LVL] == 9 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 3848 ){ Game->Counter[CR_LVL] = 10; Level10(); } } if ( Game->Counter[CR_LVL] == 9 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 10; Level10(); } } if ( Game->Counter[CR_LVL] == 10 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 11; Level11(); } } if ( Game->Counter[CR_LVL] == 10 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 5772 ){ Game->Counter[CR_LVL] = 11; Level11(); } } if ( Game->Counter[CR_LVL] == 10 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 11; Level11(); } } if ( Game->Counter[CR_LVL] == 11 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 8658 ){ Game->Counter[CR_LVL] = 12; Level12(); } } if ( Game->Counter[CR_LVL] == 11 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 12; Level12(); } } if ( Game->Counter[CR_LVL] == 12 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP] >= 2987 && Game->Counter[CR_XP_10K] > 0 ) { Game->Counter[CR_LVL] = 13; Level13(); } } if ( Game->Counter[CR_LVL] == 12 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 1 ) { Game->Counter[CR_LVL] = 13; Level13(); } } if ( Game->Counter[CR_LVL] == 13 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 9481 && Game->Counter[CR_XP_10K] > 0) { Game->Counter[CR_LVL] = 14; Level14(); } } if ( Game->Counter[CR_LVL] == 13 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 1 ) { Game->Counter[CR_LVL] = 14; Level14(); } } if ( Game->Counter[CR_LVL] == 14 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 9222 && Game->Counter[CR_XP_10K] > 1 ){ Game->Counter[CR_LVL] = 15; Level15(); } } if ( Game->Counter[CR_LVL] == 14 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 2 ) { Game->Counter[CR_LVL] = 15; Level15(); } } if ( Game->Counter[CR_LVL] == 15 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 3833 && Game->Counter[CR_XP_10K] > 3 ){ Game->Counter[CR_LVL] = 16; Level16(); } } if ( Game->Counter[CR_LVL] == 15 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 4 ) { Game->Counter[CR_LVL] = 16; Level16(); } } if ( Game->Counter[CR_LVL] == 16 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 5750 && Game->Counter[CR_XP_10K] > 5 ){ Game->Counter[CR_LVL] = 17; Level17(); } } if ( Game->Counter[CR_LVL] == 16 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 6 ) { Game->Counter[CR_LVL] = 17; Level17(); } } if ( Game->Counter[CR_LVL] == 17 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 8625 && Game->Counter[CR_XP_10K] > 8 ){ Game->Counter[CR_LVL] = 18; Level18(); } } if ( Game->Counter[CR_LVL] == 17 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 9 ) { Game->Counter[CR_LVL] = 18; Level18(); } } if ( Game->Counter[CR_LVL] == 18 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 7938 && Game->Counter[CR_XP_10K] > 13 ){ Game->Counter[CR_LVL] = 19; Level19(); } } if ( Game->Counter[CR_LVL] == 18 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 14 ) { Game->Counter[CR_LVL] = 19; Level19(); } } if ( Game->Counter[CR_LVL] == 19 && Screen->NumNPCs() == 0 ) { if ( Game->Counter[CR_XP] >= 500 && Game->Counter[CR_XP_10K] > 20 ){ Game->Counter[CR_LVL] = 20; Level20(); } } if ( Game->Counter[CR_LVL] == 19 && Screen->NumNPCs() == 0 ){ if ( Game->Counter[CR_XP_10K] > 21 ) { Game->Counter[CR_LVL] = 20; Level20(); } } } //////////////////////// /// XP TABLE /////////// //////////////////////// /// 0 = 0 //////// /// 100 = 1 //////// /// 150 = 2 //////// /// 225 = 3 //////// /// 338 = 4 //////// /// 507 = 5 //////// /// 760 = 6 //////// /// 1140 = 7 //////// /// 1710 = 8 //////// /// 2565 = 9 //////// /// 3848 = 10 //////// /// 5772 = 11 //////// /// 8658 = 12 //////// /// 12987 = 13 //////// /// 19481 = 14 //////// /// 29222 = 15 //////// /// 43833 = 16 //////// /// 65750 = 17 //////// /// 98625 = 18 //////// /// 147938 = 19 //////// /// 210500 = 20 //////// ////////////////////////////////////////// //// XP Algorithm //// //// C = Current Base //// //// H = Half Current Base //// //// N = Amount Needed for Next Level //// //// C + H = N //// //// Thus C (100) + H (50) = N (150) //// ////////////////////////////////////////// ///////////////////////// //// Bump Functions //// ///////////////////////// void increaseMP() { int amount = ( rollDie(10) + rollDie(10) + rollDie(10) ); int myst = ( getMystStat() / 2 ); int total = ( amount + myst ); Link->MP += total; Link->MaxMP += total; } void increaseHP() { int amount = ( rollDie(10) + rollDie(10) + rollDie(10) + rollDie(10) + rollDie(10) ); int body = ( getBodyStat() / 2 ); int total = ( amount + body ); Link->HP += total; Link->MaxHP += total; } //////////////////////// //// Roll Functions //// //////////////////////// int rollStat() { int r = Rand(1, 6); //specific value of 1-6 set at random; if ( r == 1 ) { int stat = CR_STAT_BODY; return stat; } else if ( r == 2 ) { int stat = CR_STAT_MIND; return stat; } else if ( r == 3 ) { int stat = CR_STAT_LUCK; return stat; } else if ( r == 4 ) { int stat = CR_STAT_MYST; return stat; } else if ( r == 5 ) { int stat = CR_STAT_INFL; return stat; } else if ( r == 6 ) { int stat = CR_STAT_MUSC; return stat; } } int rollDie(int type){ int n = Rand(1, type); return n; } int roll1d4() { int n = Rand(1, 4); return n; } int roll1d6() { int n = Rand(1, 6); return n; } int roll4d6(){ int a = Rand(1, 6); int b = Rand(1, 6); int c = Rand(1, 6); int d = Rand(1, 6); int t = ( a + b + c + d ); return t; } int roll1d8() { int n = Rand(1, 8); return n; } int roll1d10() { int n = Rand(1, 10); return n; } int roll1d12() { int n = Rand(1, 12); return n; } int roll1d20() { int n = Rand(1, 20); return n; } int roll1d50() { int n = Rand(1, 50); return n; } int roll1d100() { int n = Rand(1, 100); return n; } /////////////////////////// /// Statistic Functions /// /////////////////////////// void increaseStat() { int stat = rollStat(); int n = rollDie(6); Game->Counter[stat] += n; } //void setBodyStat(value){ //} // //void setMindStat(value){ //} // //void setLuckStat(value){ //} // //void setMystStat(value){ //} // //void setInflStat(value){ //} // //void setMuscStat(value){ //} //void setStat(stat, value){ //} int getBodyStat(){ int stat = CR_STAT_BODY; return stat; } int getMindStat(){ int stat = CR_STAT_MIND; return stat; } int getLuckStat(){ int stat = CR_STAT_LUCK; return stat; } int getMystStat(){ int stat = CR_STAT_MYST; return stat; } int getInflStat(){ int stat = CR_STAT_INFL; return stat; } int getMuscStat(){ int stat = CR_STAT_MUSC; return stat; } // Using Stats // heavy weapon script particles // discover present slot of item // set int of slot of item for bools // when trying to use the item // if CT_MUSC < x // set other slot to 'hand' until item is changed. // // Use Body to affect HP: // Use Body to set HP at level increases. Use to set HP regen rate. // Use MUSC to set-augment weapon damage, via roll1dX rands. // Use MUSC for ability to move objects. // bracelets increase Musc, as well as activating triggers. // Bracelet / gauntlet takes up a slot. Any combination of two rings, or one ring and one bracelet at one time. // Use Luck to set jinx durations. // Use Myst to set spell damage. // Require Myst of certain value to use some spells. // Ue Mind for Lore skills. // Use Mind for raw (untrained) examination checks. // Create LWeapon that deals damage based on dX rolls. // Is there any way to use MUSC and random damage on swords? // Possibly replace rhe power of the LW_SWORD generated with a sword with a different value? // INF should set the strings used on FFC scripts when conversing. // A higher INF would open up more lines of dialogue. ///////////////////////// //// Level Functions //// ///////////////////////// void Level1() { Game->PlaySound(levelSound); Screen->Message(L1String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); //Increases HP by 4d10 increaseMP(); //Increases MP by 3d10 increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level2() { Game->PlaySound(levelSound); Screen->Message(L2String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level3() { Game->PlaySound(levelSound); Screen->Message(L3String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level4() { Game->PlaySound(levelSound); Screen->Message(L4String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level5() { Game->PlaySound(levelSound); Screen->Message(L5String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. Game->Generic[GEN_CANSLASH] = 1; //This should occur when gaining this level, and be permanent. } void Level6() { Game->PlaySound(levelSound); Screen->Message(L6String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level7() { Game->PlaySound(levelSound); Screen->Message(L7String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level8() { Game->PlaySound(levelSound); Screen->Message(L8String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level9() { Game->PlaySound(levelSound); Screen->Message(L9String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level10() { Game->PlaySound(levelSound); Screen->Message(L10String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level11() { Game->PlaySound(levelSound); Screen->Message(L11String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level12() { Game->PlaySound(levelSound); Screen->Message(L12String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level13() { Game->PlaySound(levelSound); Screen->Message(L13String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level14() { Game->PlaySound(levelSound); Screen->Message(L14String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level15() { Game->PlaySound(levelSound); Screen->Message(L15String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level16() { Game->PlaySound(levelSound); Screen->Message(L16String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level17() { Game->PlaySound(levelSound); Screen->Message(L17String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level18() { Game->PlaySound(levelSound); Screen->Message(L18String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level19() { Game->PlaySound(levelSound); Screen->Message(L19String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } void Level20() { Game->PlaySound(levelSound); Screen->Message(L20String); //This should show on-screen one time, when gaining the level, and not remain forever. increaseHP(); increaseMP(); increaseStat(); //This should happen one time, when gaining this level, and be permanent. } ////////////////////////////////// /// Wallet & Pockets Functions /// ////////////////////////////////// void noFreeSpace() { if ( noFreeSpace == false ) { noFreeSpace = true; Screen->Message(NO_FREE_SPACE); //This message will be shown to the player one time, setting noFreeSpace to true. //If the player visits a bank, spends money depleting used space, or ptherwise increases space //then this flag is set back to false. The idea is to prevent displaying a message regularly. } else { Game->PlaySound(NO_SPACE_SFX); } } void spaceFreed() { noFreeSpace = false; //This is a global function that resets the noFreeSpace flag,a nd can be called from anywhere. } void checkFreeSpace() { //This fnction should be in your global while true loop. //It ensures that the noFreeSpace flag is reset if the player spends money, or deposits funds, etc. int walletFreeSpace; int pocketFreeSpace; walletFreeSpace = ( totalWalletSpace - Game->Counter[CR_SIZE_COINS_CURRENCY] ); pocketFreeSpace = ( totalPocketSpace - CR_SIZE_COINS_CURRENCY ); if ( walletFreeSpace > 5 ) { noFreeSpace = false; } if ( walletFreeSpace < 5 ){ if (pocketFreeSpace < coinsize ) { noFreeSpace = false; } } } void storeValue(){ int valueStored = Game->Counter[CR_RUPEES]; } void compareValue(){ if ( valueStored <= Game->Counter[CR_RUPEES] ) { noFreeSpace = true; } else { noFreeSpace = false; } } ///////////////////////////////////////////// /// Armour, Swords, and Shields Functions /// ///////////////////////////////////////////// void checkEatenItems() { //Place this in your main while loop, to display messages to the player if an item is eaten. if ( hasShield == false && shieldMessage == false ){ shieldMessage = true; Screen->Message(SHIELD_LOST); } if ( hasSword == false && swordMessage == false ){ swordMessage = true; Screen->Message(SWORD_LOST); } if ( hasArmour == false && swordMessage == false ){ armourMessage = true; Screen->Message(ARMOUR_LOST); } } /////////////////////// /// SKill Functions /// /////////////////////// void LoreCheckGeneric() { int loreBase; loreBase = ( loreSkill * 10 ); int loreTotal = ( loreBase + Game->Counter[CR_STAT_MIND] ); int loreDifference = ( loreTotal - loreBase ); int loreRoll = rollDie(100); bool success; int loreType; int itemToCheck; int location; int level; int skill; if ( loreRoll < loreTotal ) { //Success loreSuccess = 1; } else { //failure loreSuccess = 2; } } void makeLoreCheck(){ if ( loreSuccess == 0 ){ //do this } } void LoreCheckSuccess(bool success, int loreType, int itemToCheck, int location, int level, int skill ){ if ( loreSuccess == 0 ){ //import results from makeLoreCheck. Create a makeLoreCheck command for each item //that can use it, and each site that can use it. } } void loreLevel(){ loreSuccess = 0; //When increasing Lore, or gaining a level, reset this value. } //Possibly, use a function in the while loop with its own ints and bools. //THis function would store the lore check results and the level of the check //for every item. It wouod compare the result (0, 1, 2) to the character level, and the level at the time //that the player made the check. If the currentLevel > lastLevelForCheck, then it will allow a new check. //if the result is 0, it will always allow a check, and if the result is 2, it gives the new item. //This would keep the variables in the scope of the function, instead of as global constants and global vars. /////////////////////////// /// Item Check Functions/// /////////////////////////// void UpdateLWeapons() { // Updates every LWeapon on screen. Call in the active script. for (int i = 1; i <= Screen->NumLWeapons(); i++) { UpdateLWeapon(Screen->LoadLWeapon(i)); } } void UpdateLWeapon(lweapon lw) { // Update a given LWeapon. // If the weapon does not have it's source item marked, mark it as // being created by the last item that Link has used. if (lw->Misc[MISC_LWEAPON_ITEM] == 0) { lw->Misc[MISC_LWEAPON_ITEM] = LastItemUsed; } } //// Updates the LastItemUsed variable to our best guess at what was //// most recently used. This should be called at the end of the loop, //// right before Waitdraw or Waitframe, because the item marked in //// LastItemUsed isn't actually used until after the Waitdraw or //// Waitframe. void UpdateLastItem() { // Since we don't know which button has priority if both are pressed // at once, cancel the B button press if A has also been pressed // this frame. if ( Link->PressA && Link->PressB ) { Link->PressB = false; } // If Link is currently in an action where he obviously can't use // items, then ignore his button presses. if ( Link->Action != LA_NONE && Link->Action != LA_WALKING ) { return; } // Check which button is being pressed, if any. Also check for the // appopriate Jinx. if ( Link->PressA && Link->SwordJinx == 0 ) { LastItemUsed = GetEquipmentA(); } else if ( Link->PressB && Link->ItemJinx == 0 ) { LastItemUsed = GetEquipmentB(); } } bool IsFromItem(lweapon lw, int itemNumber) { // Return true if the given lweapon is from the given item. return lw->Misc[MISC_LWEAPON_ITEM] == itemNumber; } bool IsFromItemClass(lweapon lw, int itemClass) { // Return true if the given lweapon is from the given item class. itemdata data = Game->LoadItemData(lw->Misc[MISC_LWEAPON_ITEM]); return data->Family == itemClass; } void whipTimer(){ //Whip Cooldown Timer if ( whipCooldownTimer > 0 ) { whipCooldownTimer--; } } void goggles() { //place before waitdraw if ( gogglesOn && Link->MP ){ //Decrement magic gogglesTimer = (gogglesTimer+1) % TIME_PER_MP; if ( !gogglesTimer ) Link->MP--; Screen->Rectangle(6, 0, 0, 256, 172, 4, 1, 0, 0, 0, true, 64); if ( Link->MP <= 0 //If magic ran out && Link->Item[I_AMULET1] ) { //Take off goggles. gogglesOn = false; Link->Item[I_AMULET1] = false; // Waitframes(1); } } else if ( !gogglesOn && Link->Item[I_AMULET1] ){ //Disable Goggles Link->Item[I_AMULET1] = false; //Waitframes(1); } } // Place after waitdraw: void MCP() { if (Link->Item[231] == true) { //If Link has the fake item designated in D0 Link->Item[230] = false; //Removes the fake item user selects in D0 Link->Item[231] = false; //Removes the item the user selects in in D1 Link->MP += 256; //Increases MP by value of D3 Link->MaxMP += 256; //Increases Max MP by value of D2 } else { (Link->Item[230] == true); //Gives Link the specified item in D4. } } void secretTiners() { if(SecretTimer > -1) { SecretTimer--; if (SecretTimer == -1) { Screen->TriggerSecrets(); Game->PlaySound(27); } } } void ringTimers(){ if ( ringOn && Link->MP ){ //Decrement magic ringTimer = (ringTimer+1) % ringTimePerMP; if ( !ringTimer ) Link->MP--; //Draw shadow under Link //Screen->FastTile( 2, Link->X, Link->Y, ringShadowTile, ringShadowCset, OP_TRANS ); if ( Link->MP <= 0 //If magic ran out ){ //Take off ring ringOn = false; Link->CollDetection = true; Link->Invisible = false; } } else if ( !ringOn ){ //Disable ring Link->CollDetection = true; Link->Invisible = false; } void byrnaTimers(){ if ( byrnaOn && Link->MP ){ //Decrement magic byrnaTimer = (byrnaTimer+1) % byrnaTimePerMP; if ( !byrnaTimer ) Link->MP--; if ( Link->MP <= 0 //If magic ran out ){ //Take off ring byrnaOn = false; } } else if ( !byrnaOn ){ //Disable ring } } void bootsTimers(){ if ( bootsOn && Link->MP ){ //Decrement magic bootsTimer = (bootsTimer+1) % bootsTimePerMP; if ( !bootsTimer ) Link->MP--; if ( Link->MP <= 0 //If magic ran out || Link->Action == LA_SCROLLING //Or left screen ){ //Take off ring bootsOn = false; } } else if ( !bootsOn ){ //Disable ring } } //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<= 0) {Cooldown_ATimer--;} if (Cooldown_BTimer >= 0) {Cooldown_BTimer--;} // Block inputs. if (Cooldown_ATimer > 0) { Link->InputA = false; Link->PressA = false;} if (Cooldown_BTimer > 0) { Link->InputB = false; Link->PressB = false;} } //void DropItems(int drop, int loc) { // DropItems(drop, ComboX(loc), ComboY(loc));} // Drop an item from a dropset. // int dropset: The number of a dropset. // int x, int y or int loc: location of the drop. void DropItemSet(int drop, int x, int y) { npc n = CreateNPCAt(DROP_ENEMY_ID, x, y); n->HP = HP_SILENT; n->ItemSet = drop; } // Drop an item from a dropset. // int dropset: The number of a dropset. // int x, int y or int loc: location of the drop. void DropItemExplode(ffc this, int drop) { DropItemSet(this, drop); eweapon explosion = CreateEWeaponAt(EW_BOMBBLAST, this->X, this->Y); //explosion->CollDetection = true; //This is true by default explosion->Damage = 10; } // Drop an item from a dropset. // int dropset: The number of a dropset. // int x, int y or int loc: location of the drop. void DropItemExplodeBig(ffc this, int drop) { DropItemSet(this, drop); // One explosion every 16 frames, 15 times for(int i=0; i<15; i++) { eweapon explosion = CreateEWeaponAt(EW_SBOMBBLAST, this->X, this->Y); //explosion->CollDetection = true; //This is true by default explosion->Damage = 10; } } void bombados(){ float angle; { if (usebombodo == 1) { slower ++; if (slower == 5) { rad++; slower = 0; } angle = (angle + ORBIT_SPEED) % 360; f1 = 100 + rad * Cos(angle); f2 = 100 + rad * Sin(angle); // Screen->FastCombo(6, f1, f2, 95, 2, 128); r1 = 40+Rand(150); r2 = 40+Rand(100); slowera++; if (slowera == 20) { slowera = 0; if (bombs < 30) { bombs ++; lweapon bomb = CreateLWeaponAt(LW_BOMBBLAST, r1, r2); Game->PlaySound(SFX_BOMB); if (bombs == 30) usebombodo = 0; } } } } //////////////////// /// Item Scripts /// //////////////////// ///////////////////////////////////// /// Wallet & Pockets Item Scripts /// ///////////////////////////////////// item script moneyPickup{ void run(int coinsize, int coinvalue) { int walletFreeSpace = ( totalWalletSpace - CR_SIZE_COINS_CURRENCY ); int pocketFreeSpace = ( totalPocketSpace - CR_SIZE_COINS_CURRENCY ); if ( walletFreeSpace > coinsize ) { Game->Counter[CR_DSARI] += coinvalue; walletSpaceUsed += coinsize; //Fills wallet space. noFreeSpace = false; } else if ( walletFreeSpace < coinsize ){ if (pocketFreeSpace < coinsize ) { Game->Counter[CR_DSARI] += coinvalue; pocketSpaceUsed += coinsize; //Fills pocket space. noFreeSpace = false; } } else if ( walletFreeSpace < coinsize && pocketFreeSpace < coinsize) { noFreeSpace(); } } } item script walletPickup{ void run (int capacity){ if ( capacity == 0 ) { walletsOwned += 1; } if ( capacity > 0 ){ Game->Counter[CR_CUSTOM_WALLET_SIZE] += capacity; //Can make different sized wallets noFreeSpace = false; } } } item script pickUpEatableShield { void run(){ bool hasShield = true; bool shieldMessage = false; } } item script pickUpEatableSword{ void run() { bool hasSword = true; bool swordMessage = false; } } item script pickUpEatableArmour{ void run(){ bool hasArmour = true; bool armourMessage = false; } } /////////////////// /// FFC Scripts /// /////////////////// // D0: Item to Use // D1: Target // D2: Result //// When hit by an LWeapon satisfying the condition, change //// all combos on screen that match the condition to what //// specifies. //// //// : This is what kind of LWeapon will trigger the combo //// change. If positive, it specifies the item number that will //// trigger this (e.g. I_ARROW2 will make Silver Arrows trigger //// this). If negative or 0, it specifies the item class that will //// trigger this (e.g. -IC_ARROW will make any arrow trigger this). //// //// : This is what combos that this trigger will change when //// it is actually triggered. If positive, it specifies that all //// combos on screen with the given Combo ID will be changed (e.g. a //// 12 means change all instances of combo 12). If negative, it //// specifies that all combos on screen with the given flag will be //// changed (e.g. a -CF_SECRETS01 means to change all combos with the //// Secret 1 flag on them). //// //// : This is what the target combos are changed to. If //// positive, it specifies a combo id to change them to. If negative, //// it instead specifies a map and screen to grab combos from. The //// format is "-MMMYXX", where MMM is the map number, Y is the //// screen's Y position on that map (from 0 to 7), and XX is the //// screen's X position on that map (from 0 to 15). Every target //// combo is changed to whatever combo is at the same coordinates on //// that screen. //// //// : If positive, this causes this ffc to cancel //// if the combo underneath the ffc every changes its Combo ID. //// //// : If this is non-zero, it causes the given sound to be //// played when the trigger occurs. //// //// : If this is non-zero, it causes the given message to be //// displayed when the trigger occurs. ffc script WeaponTrigger { void run(int trigger, int target, int result, int dieOnComboChange, int sound, int message) { // Grab the combo id underneath us so we can tell when it changes. int loc = ComboAt(CenterX(this), CenterY(this)); int underComboId = Screen->ComboD[loc]; // Interpret if it is negative. int map; int screen; if (result < 0) { map = (result * -0.001) >> 0; screen = ((result * -0.01 % 10) >> 0) * 16 + (-result % 100);} // Wait for something to happen. bool waiting = true; while (waiting) { // If is set and the combo does change, terminate. if (dieOnComboChange > 0 && Screen->ComboD[loc] != underComboId) { return;} // Loop through all LWeapons on screen. for (int i = 1; i <= Screen->NumLWeapons(); i++) { lweapon lw = Screen->LoadLWeapon(i); // If the LWeapon is touching us. if (lw->CollDetection && Collision(this, lw)) { // If is positive, test the lweapon for being the // right item type. if (trigger > 0) { if (IsFromItem(lw, trigger)) { waiting = false;}} // If is negative, test the lweapon for being the // right item class. else { if (IsFromItemClass(lw, -trigger)) { waiting = false;}}}} // Advance to next frame. Waitframe();} // If we reach this point, it means that we've successfully been // hit by an acceptable LWeapon. // Now loop through every combo on screen looking for combos // matching . for (loc = 0; loc < 176; loc++) { bool match = false; // If is positive, test for Combo ID. if (target > 0) { if (Screen->ComboD[loc] == target) { match = true;}} // If is negative, test for the flag being present. else if (target < 0) { if (ComboFI(loc, -target)) { match = true;}} // If the current combo is a match, then transform the combo // according to . if (match) { // If is positive, just change the target to . if (result > 0) { Screen->ComboD[loc] = result;} // If is negative, grab the combo from the given screen. else if (result < 0) { Screen->ComboD[loc] = Game->GetComboData(map, screen, loc);}}} // Now play the message and sound, if appropriate. if (sound != 0) {Game->PlaySound(sound);} if (message != 0) {Screen->Message(message);}}} ////////////////////////////// /// Gdneric FFC Trigger v6 /// ////////////////////////////// ///////////////////// /// Enemy Scripts /// ///////////////////// ///////////////////////////////////// /// Enemy Vulnerabilities /// /// Modified from: the Gibdo Burn /// /// Script by MoscowModder /// /// Combined with the FFC Trigger /// /// Script by: grayswandir /// ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// /// Place on screen with an enemy, so that if it is killed by a specific type of weapon /// /// it spawms a different enemy. or produces a different effect. /// /// D0: Enemy Number of SOurce Enemy to Affect. /// /// D1: Enemy to Replace D0 with on Contact with Trigger. /// /// D2: Trigger - Positive Number for Specific Item Number; Negative Number of LW Type. /// ///////////////////////////////////////////////////////////////////////////////////////////// /// Place one FFC of this script on the screen for each enemy to affect by it. /// /// You can cascade this by setting the replacement enemy type as a source type in /// /// a second instance of this FFC. /// /// THis can be especially useful for spells: You can have enemies that are outwardly /// /// invincible, but are changed once affected by a spell or item. You can use the same /// /// sprite, or a variation of itl to reflect the change int he state of the enemy, or to /// /// make the change invisible to the player. /// ///////////////////////////////////////////////////////////////////////////////////////////// ffc script specialEnemyVulnerability{ void run(int enemy1, int enemy2, int trigger) { while(true){ for(int i = 1; i < Screen->NumNPCs(); i++){ //Check every enemy npc enem = Screen->LoadNPC(i); if(enem->ID == enemy1){ //If it's a the enemeny editor number of enemy1 for(int j = 1; j < Screen->NumLWeapons(); j++){ //Check every weapon lweapon weap = Screen->LoadLWeapon(j); if (weap->CollDetection && Collision(enem, weap)) { //if the LW touches the enemy, if (IsFromItem(weap, trigger)) { // If LW is from right item type. npc newEnem = CreateNPCAt(enemy2, enem->X, enem->Y); //Create the skeleton newEnem->HP = enem->HP; //Set its HP to gibdo's HP (optional; can remove this) Remove(enem); //Remove gibdo quietly } else if (IsFromItemClass(weap, -trigger)) { npc newEnem = CreateNPCAt(enemy2, enem->X, enem->Y); //Create the replacement enemy. newEnem->HP = enem->HP; //Set its HP to original enemy's HP (optional; can remove this) Remove(enem); //Remove original enemy quietly } } } } Waitframe(); } } } }