/* * Copyright 2007-2008 Ben Boeckel * * 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 . */ // Header include #include "ItemEffect.h" // Pokemod includes #include "Item.h" #include "MapWildList.h" #include "Pokemod.h" const QStringList ItemEffect::EffectStr = QStringList() << "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 QStringList ItemEffect::RelativeStr = QStringList() << "Absolute" << "Relative"; const QStringList ItemEffect::EscapeStr = QStringList() << "Anywhere" << "Dungeon"; const QStringList ItemEffect::RepelStr = QStringList() << "First" << "Max" << "All"; const QStringList ItemEffect::AmountStr = QStringList() << "All" << "One"; const QStringList ItemEffect::SpecialPhysicalStr = QStringList() << "Special" << "Physical"; const QStringList ItemEffect::BallTypeStr = QStringList() << "Regular" << "Master" << "Level" << "Love" << "Area" << "Time" << "Battle" << "Friend" << "Stat" << "Type" << "Weight"; const QStringList ItemEffect::BerryTypeStr = QStringList() << "HP Cure" << "Status Cure"; ItemEffect::ItemEffect(const ItemEffect& effect) : Object("ItemEffect", effect.parent(), effect.id()) { *this = effect; } ItemEffect::ItemEffect(const Item* parent, const int id) : Object("ItemEffect", parent, id), m_overworld(false), m_battle(false), m_held(false), m_effect(INT_MAX), m_value1(INT_MAX), m_value2(INT_MAX), m_value3(INT_MAX), m_value4(1, 1) { } ItemEffect::ItemEffect(const ItemEffect& effect, const Item* parent, const int id) : Object("ItemEffect", parent, id) { *this = effect; } ItemEffect::ItemEffect(const QDomElement& xml, const Item* parent, const int id) : Object("ItemEffect", parent, id) { load(xml, id); } void ItemEffect::validate() { TEST(setOverworld, overworld); TEST(setEffect, effect); TEST(setValue1, value1); TEST(setValue2, value2); TEST(setValue3, value3); TEST(setValue4, value4); } void ItemEffect::load(const QDomElement& xml, int id) { LOAD_ID(); LOAD(bool, overworld); LOAD(bool, battle); LOAD(bool, held); LOAD(int, effect); LOAD(int, value1); LOAD(int, value2); LOAD(int, value3); LOAD(Fraction, value4); } QDomElement ItemEffect::save() const { SAVE_CREATE(); SAVE(bool, overworld); SAVE(bool, battle); SAVE(bool, held); SAVE(int, effect); SAVE(int, value1); SAVE(int, value2); SAVE(int, value3); SAVE(Fraction, value4); return xml; } void ItemEffect::setOverworld(const bool overworld) { switch (m_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) { emit(error("Overworld mismatch")); return; } 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) { emit(error("Overworld mismatch")); return; } break; } m_overworld = overworld; emit(changed()); } void ItemEffect::setBattle(const bool battle) { m_battle = battle; emit(changed()); } void ItemEffect::setHeld(const bool held) { m_held = held; emit(changed()); } void ItemEffect::setEffect(const int effect) { if (E_End <= effect) { emit(error(bounds("effect"))); return; } 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: m_overworld = true; 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: m_overworld = false; break; } m_effect = effect; m_value1 = 0; m_value2 = INT_MAX; m_value3 = INT_MAX; m_value4.set(1, 1); emit(changed()); } void ItemEffect::setValue1(const int value1) { switch (m_effect) { case E_HPCure: case E_Revive: if ((m_value4 != R_Absolute) || !value1) { emit(error(bounds("value1"))); return; } break; case E_LevelBoost: case E_ShieldBattle: case E_PPBoost: case E_Repel: if (!value1) { emit(error(bounds("value1"))); return; } break; case E_StatBoost: case E_Acorn: if ((value1 < 0) || (65536 <= value1)) { emit(error(bounds("value1"))); return; } break; case E_ModifyStatBattle: if ((value1 < -12) || (12 < value1)) { emit(error(bounds("value1"))); return; } break; case E_Fish: case E_Coin: case E_CoinCase: break; case E_Ball: switch (m_value2) { case B_Regular: if (256 <= value1) { emit(error(bounds("value1"))); return; } break; case B_Level: if (static_cast(pokemod())->rules()->maxLevel() < value1) { emit(error(bounds("value1"))); return; } 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: emit(error(bounds("value1"))); return; } break; default: emit(warning(unused("value1"))); return; } m_value1 = value1; emit(changed()); } void ItemEffect::setValue2(const int value2) { switch (m_effect) { case E_HPCure: case E_Revive: if (R_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_CureStatus: if (Pokemod::STS_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_StatBoost: if ((value2 <= 0) || (65536 <= value2)) { emit(error(bounds("value2"))); return; } break; case E_ModifyStatBattle: if (Pokemod::ST_End_Battle <= value2) { emit(error(bounds("value2"))); return; } break; case E_ShieldBattle: if (SP_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_TypeBoost: if (static_cast(pokemod())->typeIndex(value2) == INT_MAX) { emit(error(bounds("value2"))); return; } break; case E_PPRestore: if (A_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_Repel: if (RP_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_Escape: if (ES_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_TM: case E_HM: if (static_cast(pokemod())->moveIndex(value2) == INT_MAX) { emit(error(bounds("value2"))); return; } break; case E_Ball: if (B_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_Scope: break; case E_Berry: if (B2_End <= value2) { emit(error(bounds("value2"))); return; } break; case E_Coin: case E_CoinCase: if (value2 <= 0) { emit(error(bounds("value2"))); return; } break; case E_Acorn: if (static_cast(pokemod())->itemIndex(value2) == INT_MAX) { emit(error(bounds("value2"))); return; } break; default: emit(warning(unused("value2"))); return; } m_value2 = value2; emit(changed()); } void ItemEffect::setValue3(const int value3) { switch (m_effect) { case E_StatBoost: if ((static_cast(pokemod())->rules()->specialSplit() ? Pokemod::ST_End_GSC : Pokemod::ST_End_RBY) <= value3) { emit(error(bounds("value3"))); return; } break; case E_Ball: switch (m_value2) { case B_Level: case B_Friend: case B_Weight: break; case B_Area: if (MapWildList::End <= value3) { emit(error(bounds("value3"))); return; } break; case B_Time: if (static_cast(pokemod())->timeIndex(value3) == INT_MAX) { emit(error(bounds("value3"))); return; } break; case B_Stat: if ((static_cast(pokemod())->rules()->specialSplit() ? Pokemod::ST_End_GSC : Pokemod::ST_End_RBY) <= value3) { emit(error(bounds("value3"))); return; } break; case B_Type: if (static_cast(pokemod())->typeIndex(value3) == INT_MAX) { emit(error(bounds("value3"))); return; } break; case B_Regular: case B_Master: case B_Love: case B_Battle: emit(warning(unused("value3"))); return; } break; case E_Berry: switch (m_value2) { case B2_HPCure: if (Pokemod::REL_End <= value3) { emit(error(bounds("value3"))); return; } break; case B2_StatusCure: if (Pokemod::STS_End <= value3) { emit(error(bounds("value3"))); return; } break; default: emit(warning(unused("value3"))); return; } break; default: emit(warning(unused("value3"))); return; } m_value3 = value3; emit(changed()); } void ItemEffect::setValue4(const Fraction& value4) { if ((E_TypeBoost == m_effect) || (E_PPBoost == m_effect)) { if (value4 < 1) { emit(error(bounds("value4"))); return; } } else if (1 < value4) { emit(error(bounds("value4"))); return; } switch (m_effect) { case E_CureStatus: case E_LevelBoost: case E_StatBoost: case E_ModifyStatBattle: case E_Fish: 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: { emit(warning(unused("value4"))); return; } case E_Ball: if (m_value2 == B_Master) { emit(warning(unused("value4"))); return; } break; case E_Berry: if (m_value2 != B2_HPCure) { emit(warning(unused("value4"))); return; } break; } m_value4 = value4; emit(changed()); } bool ItemEffect::overworld() const { return m_overworld; } bool ItemEffect::battle() const { return m_battle; } bool ItemEffect::held() const { return m_held; } int ItemEffect::effect() const { return m_effect; } int ItemEffect::value1() const { return m_value1; } int ItemEffect::value2() const { return m_value2; } int ItemEffect::value3() const { return m_value3; } Fraction ItemEffect::value4() const { return m_value4; } ItemEffect& ItemEffect::operator=(const ItemEffect& rhs) { if (this == &rhs) return *this; COPY(overworld); COPY(battle); COPY(held); COPY(effect); COPY(value1); COPY(value2); COPY(value3); COPY(value4); return *this; }