///////////////////////////////////////////////////////////////////////////// // Name: pokemod/ItemEffect.cpp // Purpose: Define an effect of an item // Author: Ben Boeckel // Modified by: Ben Boeckel // Created: Tue Mar 20 18:25:26 2007 // Copyright: ©2007 Ben Boeckel and Nerdy Productions // Licence: // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . ///////////////////////////////////////////////////////////////////////////// #include "ItemEffect.h" const char* PokeGen::PokeMod::ItemEffect::EffectStr[PokeGen::PokeMod::ItemEffect::E_End] = {"HP Cure", "Revive", "Cure Status", "Level Boost", "Stat Boost", "Flinch", "Go First", "Keep Alive", "Modify Stat (Battle Only)", "Shield (Battle Only)", "Run (Battle Only)", "PP Boost", "Type Boost", "PP Restore", "Experience Share", "Fishing Rod", "Repel", "Escape", "TM", "HM", "Map", "Ball", "Itemfinder", "Bike", "Scope", "Coin", "Coin Case", "Berry", "Acorn"}; const char* PokeGen::PokeMod::ItemEffect::RelativeStr[PokeGen::PokeMod::ItemEffect::R_End] = {"Absolute", "Relative"}; const char* PokeGen::PokeMod::ItemEffect::EscapeStr[PokeGen::PokeMod::ItemEffect::ES_End] = {"Anywhere", "Dungeon"}; const char* PokeGen::PokeMod::ItemEffect::RepelStr[PokeGen::PokeMod::ItemEffect::RP_End] = {"First", "Max", "All"}; const char* PokeGen::PokeMod::ItemEffect::AmountStr[PokeGen::PokeMod::ItemEffect::A_End] = {"All", "One"}; const char* PokeGen::PokeMod::ItemEffect::SpecialPhysicalStr[PokeGen::PokeMod::ItemEffect::SP_End] = {"Special", "Physical"}; const char* PokeGen::PokeMod::ItemEffect::BallTypeStr[PokeGen::PokeMod::ItemEffect::B_End] = {"Regular", "Master", "Level", "Love", "Area", "Time", "Battle", "Friend", "Stat", "Type", "Weight"}; const char* PokeGen::PokeMod::ItemEffect::BerryTypeStr[PokeGen::PokeMod::ItemEffect::B2_End] = {"HP Cure", "Status Cure"}; PokeGen::PokeMod::ItemEffect::ItemEffect(const Pokemod* par, const unsigned _id) : Object(_id, par), overworld(false), battle(false), held(false), effect(UINT_MAX), val1(INT_MIN), val2(UINT_MAX), val3(UINT_MAX), val4(1, 1) { } PokeGen::PokeMod::ItemEffect::ItemEffect(const Pokemod* par, Ini& ini, const unsigned _id) : Object(_id, par) { ImportIni(ini, _id); } bool PokeGen::PokeMod::ItemEffect::Validate() { pokemod->ValidationMsg(QString("------Effect with id %1---").arg(id), Pokemod::V_Msg); switch (effect) { case E_Revive: case E_LevelBoost: case E_StatBoost: case E_PPBoost: case E_Fish: case E_Repel: case E_Escape: case E_TM: case E_HM: case E_Map: case E_Itemfinder: case E_Bike: case E_Scope: case E_Coin: case E_CoinCase: case E_Acorn: case E_Evolution: if (!overworld) { isValid = false; pokemod->ValidationMsg("Effect only works in the overworld"); } break; case E_Flinch: case E_First: case E_KeepAlive: case E_ModifyStatBattle: case E_ShieldBattle: case E_RunBattle: case E_TypeBoost: case E_ExpShare: case E_Ball: case E_Berry: if (overworld) { isValid = false; pokemod->ValidationMsg("Effect cannot work in the overworld"); } break; } if (effect < E_End) { bool ok = true; switch (effect) { case E_HPCure: case E_Revive: if ((val4 != R_Absolute) || !val1) ok = false;; break; case E_LevelBoost: case E_ShieldBattle: case E_PPBoost: case E_Repel: if (!val1) ok = false; break; case E_StatBoost: case E_Acorn: if ((val1 < 0) || (65536 <= val1)) ok = false; break; case E_ModifyStatBattle: if ((val1 < -6) || (6 < val1)) ok = false; break; case E_Ball: switch (val2) { case B_Regular: if (256 <= (unsigned)val1) ok = false; break; case B_Level: if (pokemod->GetMaxLevel() < (unsigned)val1) ok = false; break; case B_Master: case B_Love: case B_Area: case B_Time: case B_Battle: case B_Friend: case B_Stat: case B_Type: case B_Weight: break; default: ok = false; break; } break; } if (!ok) { pokemod->ValidationMsg("Invalid val1"); isValid = false; ok = true; } switch (effect) { case E_HPCure: case E_Revive: if (R_End <= val2) ok = false; break; case E_CureStatus: if (STS_End <= val2) ok = false; break; case E_StatBoost: if ((val2 <= 0) || (65536 <= val2)) ok = false; break; case E_ModifyStatBattle: if (ST_End_Battle <= val2) ok = false; break; case E_ShieldBattle: if (SP_End <= val2) ok = false; break; case E_TypeBoost: if (pokemod->GetTypeByID(val2) == UINT_MAX) ok = false; break; case E_PPRestore: if (A_End <= val2) ok = false; break; case E_Repel: if (RP_End <= val2) ok = false; break; case E_Escape: if (ES_End <= val2) ok = false; break; case E_TM: case E_HM: if (pokemod->GetMoveByID(val2) == UINT_MAX) ok = false; break; case E_Ball: if (B_End <= val2) ok = false; break; case E_Berry: if (B2_End <= val2) ok = false; break; case E_Coin: case E_CoinCase: if (val2 <= 0) ok = false; break; case E_Acorn: if (pokemod->GetItemByID(val2) == UINT_MAX) ok = false; break; } if (!ok) { pokemod->ValidationMsg("Invalid val2"); isValid = false; ok = true; } switch (effect) { case E_StatBoost: if ((pokemod->IsSpecialSplit() ? ST_End_GSC : ST_End_RBY) <= val3) ok = false; break; case E_Ball: switch (val2) { case B_Regular: case B_Master: case B_Level: case B_Love: case B_Battle: case B_Friend: case B_Weight: break; case B_Area: if (MapWildList::End <= val3) ok = false; break; case B_Time: if (pokemod->GetTimeByID(val3) == UINT_MAX) ok = false; break; case B_Stat: if ((pokemod->IsSpecialSplit() ? ST_End_GSC : ST_End_RBY) <= val3) ok = false; break; case B_Type: if (pokemod->GetTypeByID(val3) == UINT_MAX) ok = false; break; } break; case E_Berry: switch (val2) { case B2_HPCure: if (REL_End <= val3) ok = false; break; case B2_StatusCure: if (STS_End <= val3) ok = false; break; default: ok = false; } break; } if (!ok) { pokemod->ValidationMsg("Invalid val3"); isValid = false; } } else { pokemod->ValidationMsg("Invalid effect"); isValid = false; } return isValid; } void PokeGen::PokeMod::ItemEffect::ImportIni(Ini& ini, const unsigned _id) { if (_id == UINT_MAX) ini.GetValue("id", id); else id = _id; unsigned i; unsigned j; ini.GetValue("overworld", overworld, false); ini.GetValue("battle", battle, false); ini.GetValue("held", held, false); ini.GetValue("effect", effect); ini.GetValue("val1", val1); ini.GetValue("val2", val2); ini.GetValue("val3", val3); ini.GetValue("val4-n", i, 1); ini.GetValue("val4-n", j, 1); val4.Set(i, j); } void PokeGen::PokeMod::ItemEffect::ExportIni(QFile& fout, const QString& item) const { Ini exItemEffect(item + " itemEffect"); exItemEffect.AddField("id", id); exItemEffect.AddField("overworld", overworld); exItemEffect.AddField("battle", battle); exItemEffect.AddField("held", held); exItemEffect.AddField("effect", effect); exItemEffect.AddField("val1", val1); exItemEffect.AddField("val2", val2); exItemEffect.AddField("val3", val3); exItemEffect.AddField("val4-n", val4.GetNum()); exItemEffect.AddField("val4-d", val4.GetDenom()); exItemEffect.Export(fout); } bool PokeGen::PokeMod::ItemEffect::SetOverworld(const bool o) { switch (effect) { case E_Revive: case E_LevelBoost: case E_StatBoost: case E_PPBoost: case E_Fish: case E_Repel: case E_Escape: case E_TM: case E_HM: case E_Map: case E_Itemfinder: case E_Bike: case E_Scope: case E_Coin: case E_CoinCase: case E_Acorn: case E_Evolution: if (!o) return false; case E_Flinch: case E_First: case E_KeepAlive: case E_ModifyStatBattle: case E_ShieldBattle: case E_RunBattle: case E_TypeBoost: case E_ExpShare: case E_Ball: case E_Berry: if (o) return false; } overworld = o; return true; } void PokeGen::PokeMod::ItemEffect::SetBattle(const bool b) { battle = b; } void PokeGen::PokeMod::ItemEffect::SetHeld(const bool h) { held = h; } bool PokeGen::PokeMod::ItemEffect::SetEffect(const unsigned e) { if (e < E_End) { switch (e) { case E_Revive: case E_LevelBoost: case E_StatBoost: case E_PPBoost: case E_Fish: case E_Repel: case E_Escape: case E_TM: case E_HM: case E_Map: case E_Itemfinder: case E_Bike: case E_Scope: case E_Coin: case E_CoinCase: case E_Acorn: case E_Evolution: if (!overworld) return false; case E_Flinch: case E_First: case E_KeepAlive: case E_ModifyStatBattle: case E_ShieldBattle: case E_RunBattle: case E_TypeBoost: case E_ExpShare: case E_Ball: case E_Berry: if (overworld) return false; } effect = e; val1 = INT_MIN; val2 = UINT_MAX; val3 = UINT_MAX; val4.Set(1, 1, ((e == E_TypeBoost) || (e == E_PPBoost)) ? Frac::Over1 : Frac::Proper); } return (effect == e); } bool PokeGen::PokeMod::ItemEffect::SetVal1(const int v1) { switch (effect) { case E_HPCure: case E_Revive: if ((val4 == R_Absolute) && v1) val1 = v1; break; case E_LevelBoost: case E_ShieldBattle: case E_PPBoost: case E_Repel: if (v1) val1 = v1; break; case E_StatBoost: case E_Acorn: if ((0 <= v1) && (v1 < 65536)) val1 = v1; break; case E_ModifyStatBattle: if ((-6 <= v1) && (v1 <= 6)) val1 = v1; break; case E_Fish: case E_Coin: case E_CoinCase: val1 = v1; break; case E_Ball: switch (val2) { case B_Regular: if ((unsigned)v1 < 256) val1 = (unsigned)v1; break; case B_Level: if ((unsigned)v1 <= pokemod->GetMaxLevel()) val1 = (unsigned)v1; break; case B_Battle: case B_Friend: case B_Stat: val1 = v1; break; } break; } return (val1 == v1); } bool PokeGen::PokeMod::ItemEffect::SetVal2(const unsigned v2) { switch (effect) { case E_HPCure: case E_Revive: if (v2 < R_End) val2 = v2; break; case E_CureStatus: if (v2 < STS_End) val2 = v2; break; case E_StatBoost: if ((0 < v2) && (v2 < 65536)) val2 = v2; break; case E_ModifyStatBattle: if (v2 < ST_End_Battle) val2 = v2; break; case E_ShieldBattle: if (v2 < SP_End) val2 = v2; break; case E_TypeBoost: if (pokemod->GetTypeByID(v2) != UINT_MAX) val2 = v2; break; case E_PPRestore: if (v2 < A_End) val2 = v2; break; case E_Repel: if (v2 < RP_End) val2 = v2; break; case E_Escape: if (v2 < ES_End) val2 = v2; break; case E_TM: case E_HM: if (pokemod->GetMoveByID(v2) != UINT_MAX) val2 = v2; break; case E_Ball: if (v2 < B_End) { val2 = v2; val4.SetType(Frac::Improper); } break; case E_Berry: if (v2 < B2_End) val2 = v2; break; case E_Coin: case E_CoinCase: if (0 < v2) val2 = v2; break; case E_Acorn: if (pokemod->GetItemByID(v2) != UINT_MAX) val2 = v2; break; } return (val2 == v2); } bool PokeGen::PokeMod::ItemEffect::SetVal3(const unsigned v3) { switch (effect) { case E_StatBoost: if (v3 < (pokemod->IsSpecialSplit() ? ST_End_GSC : ST_End_RBY)) val3 = v3; break; case E_Ball: switch (val2) { case B_Level: case B_Friend: case B_Weight: val3 = v3; break; case B_Area: if (v3 < MapWildList::End) val3 = v3; break; case B_Time: if (pokemod->GetTimeByID(v3) != UINT_MAX) val3 = v3; break; case B_Stat: if (v3 < (pokemod->IsSpecialSplit() ? ST_End_GSC : ST_End_RBY)) val3 = v3; break; case B_Type: if (pokemod->GetTypeByID(v3) != UINT_MAX) val3 = v3; break; } break; case E_Berry: switch (val2) { case B2_HPCure: if (v3 < REL_End) val3 = v3; break; case B2_StatusCure: if (v3 < STS_End) val3 = v3; break; } break; } return (val3 == v3); } bool PokeGen::PokeMod::ItemEffect::SetVal4(const unsigned n, const unsigned d) { switch (effect) { case E_HPCure: case E_Revive: case E_Flinch: case E_First: case E_KeepAlive: case E_ShieldBattle: case E_RunBattle: case E_PPBoost: case E_TypeBoost: case E_PPRestore: case E_ExpShare: case E_Repel: return val4.Set(n, d); case E_Ball: if (val2 != B_Master) return val4.Set(n, d); case E_Berry: if (val2 == B2_HPCure) return val4.Set(n, d); } return false; } bool PokeGen::PokeMod::ItemEffect::SetVal4Num(const unsigned n) { switch (effect) { case E_HPCure: case E_Revive: case E_Flinch: case E_First: case E_KeepAlive: case E_ShieldBattle: case E_RunBattle: case E_PPBoost: case E_TypeBoost: case E_PPRestore: case E_ExpShare: case E_Repel: return val4.SetNum(n); case E_Ball: if (val2 != B_Master) return val4.SetNum(n); case E_Berry: if (val2 == B2_HPCure) return val4.SetNum(n); } return false; } bool PokeGen::PokeMod::ItemEffect::SetVal4Denom(const unsigned d) { switch (effect) { case E_HPCure: case E_Revive: case E_Flinch: case E_First: case E_KeepAlive: case E_ShieldBattle: case E_RunBattle: case E_PPBoost: case E_TypeBoost: case E_PPRestore: case E_ExpShare: case E_Repel: return val4.SetDenom(d); case E_Ball: if (val2 != B_Master) return val4.SetDenom(d); case E_Berry: if (val2 == B2_HPCure) return val4.SetDenom(d); } return true; } bool PokeGen::PokeMod::ItemEffect::GetOverworld() const { return overworld; } bool PokeGen::PokeMod::ItemEffect::GetBattle() const { return battle; } bool PokeGen::PokeMod::ItemEffect::GetHeld() const { return held; } unsigned PokeGen::PokeMod::ItemEffect::GetEffect() const { return effect; } int PokeGen::PokeMod::ItemEffect::GetVal1() const { return val1; } unsigned PokeGen::PokeMod::ItemEffect::GetVal2() const { return val2; } unsigned PokeGen::PokeMod::ItemEffect::GetVal3() const { return val3; } PokeGen::Frac PokeGen::PokeMod::ItemEffect::GetVal4() const { return val4; } unsigned PokeGen::PokeMod::ItemEffect::GetVal4Num() const { return val4.GetNum(); } unsigned PokeGen::PokeMod::ItemEffect::GetVal4Denom() const { return val4.GetDenom(); }