/* * 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 . */ // Qt includes #include #include #include #include // Pokemod includes #include "Ability.h" #include "Author.h" #include "Badge.h" #include "CoinList.h" #include "Dialog.h" #include "EggGroup.h" #include "Item.h" #include "ItemType.h" #include "Map.h" #include "Move.h" #include "Nature.h" #include "Species.h" #include "Store.h" #include "Tile.h" #include "Time.h" #include "Trainer.h" #include "Type.h" // Header include #include "Pokemod.h" const QStringList Pokemod::ValidationStr = QStringList() << "Message" << "Warn" << "Error"; const QStringList Pokemod::StatRBYStr = QStringList() << "HP" << "Attack" << "Defense" << "Speed" << "Special" << "Special" << "Accuracy" << "Evasion"; const QStringList Pokemod::StatGSCStr = QStringList() << "HP" << "Attack" << "Defense" << "Speed" << "Special Attack" << "Special Defense" << "Accuracy" << "Evasion"; const QStringList Pokemod::BattleMemberStr = QStringList() << "Player" << "Enemy"; const QStringList Pokemod::WeatherStr = QStringList() << "Ice" << "Rain" << "Sun" << "Sand" << "All"; const QStringList Pokemod::DirectionStr = QStringList() << "Up" << "Down" << "Left" << "Right" << "None"; const QStringList Pokemod::RelativeStr = QStringList() << "Less" << "Less or Equal" << "Greater or Equal" << "Greater" << "Equal" << "Not Equal"; const QStringList Pokemod::StatusStr = QStringList() << "Freeze" << "Paralyze" << "Sleep" << "Poison" << "Toxic Poison" << "Burn" << "Any"; const QStringList Pokemod::HMStr = QStringList() << "Cut" << "Fly" << "Surf" << "Strength" << "Flash" << "Whirlpool" << "Waterfall" << "Dive" << "Headbutt" << "Rock Smash" << "Defog" << "Rock Climb" << "Heal" << "Escape"; Pokemod::Pokemod() : Object("Pokemod", this, 0), valOutput(NULL), m_title(""), m_version(""), m_description(""), m_startMap(INT_MAX), m_startWarp(INT_MAX), m_superPCUname(""), m_superPCPasswd(""), m_typeChart(0, 0),//, Frac(1, 1, Frac::Improper)), m_rules(this) { } Pokemod::Pokemod(const Pokemod& pokemod) : Object("Pokemod", this, 0), m_rules(this) { *this = pokemod; } Pokemod::Pokemod(const QDomElement& xml) : Object("Pokemod", this, 0), valOutput(NULL), m_rules(this) { load(xml); } Pokemod::~Pokemod() { clear(); } bool Pokemod::validate() const { bool valid = true; validationMsg(QString("Pokemod \"%1\"").arg(m_title), V_Msg); if (m_title == "") { validationMsg("Title is not defined"); valid = false; } if (m_version == "") { validationMsg("Version is not defined"); valid = false; } if (m_description == "") validationMsg("Description is not defined", V_Warn); if (mapIndex(m_startMap)) { if (mapById(m_startMap)->warpIndex(m_startWarp) == INT_MAX) { validationMsg("Invalid starting warp"); valid = false; } } else { validationMsg("Invalid starting map"); valid = false; } if (m_superPCUname == "") validationMsg("Super PC username not defined", V_Warn); if (m_superPCPasswd == "") validationMsg("Super PC password not defined", V_Warn); if ((m_typeChart.width() != typeCount()) || (m_typeChart.height() != typeCount())) { validationMsg("TypeChart is invalid"); valid = false; } if (!m_rules.isValid()) valid = false; QMap idChecker; QMap timeChecker; if (m_rules.abilityAllowed()) { if (!abilityCount()) { validationMsg("There are no abilities"); valid = false; } foreach (Ability* ability, m_abilities) { if (!ability->isValid()) valid = false; if (idChecker[ability->id()]) validationMsg(QString("Duplicate ability with id %1").arg(ability->id())); idChecker[ability->id()] = true; } idChecker.clear(); } if (!authorCount()) { validationMsg("There are no authors"); valid = false; } foreach (Author* author, m_authors) { if (!author->isValid()) valid = false; if (idChecker[author->id()]) validationMsg(QString("Duplicate author with id %1").arg(author->id())); idChecker[author->id()] = true; } idChecker.clear(); if (!badgeCount()) validationMsg("There are no badges", V_Warn); foreach (Badge* badge, m_badges) { if (!badge->isValid()) valid = false; if (idChecker[badge->id()]) validationMsg(QString("Duplicate badge with id %1").arg(badge->id())); idChecker[badge->id()] = true; } idChecker.clear(); if (!coinListCount()) validationMsg("There are no coin lists", V_Warn); foreach (CoinList* coinList, m_coinLists) { if (!coinList->isValid()) valid = false; if (idChecker[coinList->id()]) validationMsg(QString("Duplicate coin list with id %1").arg(coinList->id())); idChecker[coinList->id()] = true; } idChecker.clear(); if (!dialogCount()) { validationMsg("There are no dialogs"); valid = false; } foreach (Dialog* dialog, m_dialogs) { if (!dialog->isValid()) valid = false; if (idChecker[dialog->id()]) validationMsg(QString("Duplicate dialog with id %1").arg(dialog->id())); idChecker[dialog->id()] = true; } idChecker.clear(); if (m_rules.breedingAllowed()) { if (!eggGroupCount()) { validationMsg("There are no egg grous"); valid = false; } foreach (EggGroup* eggGroup, m_eggGroups) { if (!eggGroup->isValid()) valid = false; if (idChecker[eggGroup->id()]) validationMsg(QString("Duplicate egg group with id %1").arg(eggGroup->id())); idChecker[eggGroup->id()] = true; } idChecker.clear(); } if (!itemCount()) validationMsg("There are no m_items", V_Warn); foreach (Item* item, m_items) { if (!item->isValid()) valid = false; if (idChecker[item->id()]) validationMsg(QString("Duplicate item with id %1").arg(item->id())); idChecker[item->id()] = true; } idChecker.clear(); if (!itemTypeCount()) { validationMsg("There are no item types", itemCount() ? V_Error : V_Warn); if (itemCount()) valid = false; } foreach (ItemType* itemType, m_itemTypes) { if (!itemType->isValid()) valid = false; if (idChecker[itemType->id()]) validationMsg(QString("Duplicate item type with id %1").arg(itemType->id())); idChecker[itemType->id()] = true; } idChecker.clear(); if (!mapCount()) { validationMsg("There are no m_maps"); valid = false; } foreach (Map* map, m_maps) { if (!map->isValid()) valid = false; if (idChecker[map->id()]) validationMsg(QString("Duplicate map with id %1").arg(map->id())); idChecker[map->id()] = true; } idChecker.clear(); if (!moveCount()) { validationMsg("There are no m_moves"); valid = false; } foreach (Move* move, m_moves) { if (!move->isValid()) valid = false; if (idChecker[move->id()]) validationMsg(QString("Duplicate move with id %1").arg(move->id())); idChecker[move->id()] = true; } idChecker.clear(); if (m_rules.natureAllowed()) { if (!natureCount()) { validationMsg("There are no natures"); valid = false; } foreach (Nature* nature, m_natures) { if (!nature->isValid()) valid = false; if (idChecker[nature->id()]) validationMsg(QString("Duplicate ability with id %1").arg(nature->id())); idChecker[nature->id()] = true; } idChecker.clear(); } if (!speciesCount()) { validationMsg("There are no m_species"); valid = false; } foreach (Species* m_species, m_species) { if (!m_species->isValid()) valid = false; if (idChecker[m_species->id()]) validationMsg(QString("Duplicate m_species with id %1").arg(m_species->id())); idChecker[m_species->id()] = true; } idChecker.clear(); if (!storeCount()) validationMsg("There are no m_stores", V_Warn); foreach (Store* store, m_stores) { if (!store->isValid()) valid = false; if (idChecker[store->id()]) validationMsg(QString("Duplicate store with id %1").arg(store->id())); idChecker[store->id()] = true; } idChecker.clear(); if (!tileCount()) { validationMsg("There are no m_tiles"); valid = false; } foreach (Tile* tile, m_tiles) { if (!tile->isValid()) valid = false; if (idChecker[tile->id()]) validationMsg(QString("Duplicate tile with id %1").arg(tile->id())); idChecker[tile->id()] = true; } idChecker.clear(); if (!trainerCount()) { validationMsg("There are no times", Pokemod::V_Warn); } foreach (Trainer* trainer, m_trainers) { if (!trainer->isValid()) valid = false; if (idChecker[trainer->id()]) validationMsg(QString("Duplicate trainer with id %1").arg(trainer->id())); idChecker[trainer->id()] = true; } idChecker.clear(); if (!timeCount()) { validationMsg("There are no times"); valid = false; } foreach (Time* time, m_times) { if (!time->isValid()) valid = false; if (idChecker[time->id()]) validationMsg(QString("Duplicate time with id %1").arg(time->id())); idChecker[time->id()] = true; if (timeChecker[(60 * time->hour()) + time->minute()]) validationMsg(QString("Duplicate time at %1:%2").arg(time->hour()).arg(time->minute())); timeChecker[(60 * time->hour()) + time->minute()] = true; } idChecker.clear(); if (!typeCount()) { validationMsg("There are no types"); valid = false; } foreach (Type* type, m_types) { if (!type->isValid()) valid = false; if (idChecker[type->id()]) validationMsg(QString("Duplicate type with id %1").arg(type->id())); idChecker[type->id()] = true; } return valid; } void Pokemod::load(const QDomElement& xml, const int) throw(Exception) { clear(); LOAD(QString, title); LOAD(QString, version); LOAD(QString, description); LOAD(int, startMap); LOAD(int, startWarp); LOAD(QPixmap, walkSkin); LOAD(QPixmap, bikeSkin); LOAD(QPixmap, surfSkin); LOAD(QPixmap, flySkin); LOAD(QPixmap, fishSkin); LOAD(QPixmap, surfFishSkin); LOAD(QString, superPCUname); LOAD(QString, superPCPasswd); LOAD(Rules, rules); LOAD_SUB(newAbility, abilities); LOAD_SUB(newAuthor, authors); LOAD_SUB(newBadge, badges); LOAD_SUB(newCoinList, coinLists); LOAD_SUB(newDialog, dialogs); LOAD_SUB(newEggGroup, eggGroups); LOAD_SUB(newItem, items); LOAD_SUB(newItemType, itemTypes); LOAD_SUB(newMap, maps); LOAD_SUB(newMove, moves); LOAD_SUB(newNature, natures); LOAD_SUB(newSpecies, species); LOAD_SUB(newStore, stores); LOAD_SUB(newTile, tiles); LOAD_SUB(newTime, times); LOAD_SUB(newTrainer, trainers); LOAD_SUB(newType, types); LOAD_MATRIX(setTypeChart, Frac, typeChart); } QDomElement Pokemod::save() const { QDomElement xml; xml.setTagName(className()); SAVE(QString, title); SAVE(QString, version); SAVE(QString, description); SAVE(int, startMap); SAVE(int, startWarp); SAVE(QPixmap, walkSkin); SAVE(QPixmap, bikeSkin); SAVE(QPixmap, surfSkin); SAVE(QPixmap, flySkin); SAVE(QPixmap, fishSkin); SAVE(QPixmap, surfFishSkin); SAVE(QString, superPCUname); SAVE(QString, superPCPasswd); xml.appendChild(m_rules.save()); SAVE_MATRIX(Frac, typeChart); SAVE_SUB(Ability, abilities); SAVE_SUB(Author, authors); SAVE_SUB(Badge, badges); SAVE_SUB(CoinList, coinLists); SAVE_SUB(Dialog, dialogs); SAVE_SUB(EggGroup, eggGroups); SAVE_SUB(Item, items); SAVE_SUB(ItemType, itemTypes); SAVE_SUB(Map, maps); SAVE_SUB(Move, moves); SAVE_SUB(Nature, natures); SAVE_SUB(Species, species); SAVE_SUB(Store, stores); SAVE_SUB(Tile, tiles); SAVE_SUB(Time, times); SAVE_SUB(Trainer, trainers); SAVE_SUB(Type, types); return xml; } int Pokemod::maxCompatability(const Pokemod& pokemod) const { // TODO: MaxCompatability between two versions } void Pokemod::validationMsg(const QString& msg, Validation val) const throw(Exception) { if (!valOutput) throw(Exception(className(), "valOutput isn\'t set")); if (V_End < val) throw(BoundsException(className(), "val")); (*valOutput) << ValidationStr[val] << QDateTime::currentDateTime().toString(" (yyyyMMdd hh:mm:ss.zzz ddd): ") << msg; } void Pokemod::setValOutput(QStringList& s) { valOutput = &s; } void Pokemod::unsetValOutput() { valOutput = NULL; } void Pokemod::setTitle(const QString& title) { m_title = title; } void Pokemod::setVersion(const QString& version) { m_version = version; } void Pokemod::setDescription(const QString& description) { m_description = description; } void Pokemod::setStartMap(const int startMap) throw(BoundsException) { if (mapIndex(startMap) == INT_MAX) throw(BoundsException(className(), "startMap")); m_startMap = startMap; } void Pokemod::setStartWarp(const int startWarp) throw(BoundsException) { if (mapIndex(m_startMap) == INT_MAX) throw(BoundsException(className(), "startMap")); if (mapById(m_startMap)->warpIndex(startWarp) == INT_MAX) throw(BoundsException(className(), "startWarp")); m_startWarp = startWarp; } void Pokemod::setWalkSkin(const QPixmap& walkSkin) throw(Exception) { // TODO: check dimensions m_walkSkin = walkSkin; } void Pokemod::setBikeSkin(const QPixmap& bikeSkin) throw(Exception) { // TODO: check dimensions m_bikeSkin = bikeSkin; } void Pokemod::setSurfSkin(const QPixmap& surfSkin) throw(Exception) { // TODO: check dimensions m_surfSkin = surfSkin; } void Pokemod::setFlySkin(const QPixmap& flySkin) throw(Exception) { // TODO: check dimensions m_flySkin = flySkin; } void Pokemod::setFishSkin(const QPixmap& fishSkin) throw(Exception) { // TODO: check dimensions m_fishSkin = fishSkin; } void Pokemod::setSurfFishSkin(const QPixmap& surfFishSkin) throw(Exception) { // TODO: check dimensions m_surfFishSkin = surfFishSkin; } void Pokemod::setSuperPCUname(const QString& username) { m_superPCUname = username; } void Pokemod::setSuperPCPasswd(const QString& password) { m_superPCPasswd = password; } void Pokemod::setTypeChart(const int attack, const int defense, const Frac& multiplier) throw(Exception) { m_typeChart(attack, defense) = multiplier; } void Pokemod::setRules(const Rules& rules) { m_rules = rules; } void Pokemod::setRules(const QDomElement& xml) { m_rules.load(xml); } QString Pokemod::title() const { return m_title; } QString Pokemod::version() const { return m_version; } QString Pokemod::description() const { return m_description; } int Pokemod::startMap() const { return m_startMap; } int Pokemod::startWarp() const { return m_startWarp; } QPixmap Pokemod::walkSkin() const { return m_walkSkin; } QPixmap Pokemod::bikeSkin() const { return m_bikeSkin; } QPixmap Pokemod::surfSkin() const { return m_surfSkin; } QPixmap Pokemod::flySkin() const { return m_flySkin; } QPixmap Pokemod::fishSkin() const { return m_fishSkin; } QPixmap Pokemod::surfFishSkin() const { return m_surfFishSkin; } QString Pokemod::superPCUname() const { return m_superPCUname; } QString Pokemod::superPCPasswd() const { return m_superPCPasswd; } const Matrix* Pokemod::typeChart() const { return &m_typeChart; } Matrix* Pokemod::typeChart() { return &m_typeChart; } Frac Pokemod::typeChart(const int attack, const int defense) const { return m_typeChart(attack, defense); } const Rules* Pokemod::rules() const { return &m_rules; } Rules* Pokemod::rules() { return &m_rules; } const Ability* Pokemod::ability(const int index) const throw(IndexException) { if (abilityCount() <= index) error("ability"); return m_abilities.at(index); } Ability* Pokemod::ability(const int index) throw(IndexException) { if (abilityCount() <= index) error("ability"); return m_abilities[index]; } const Ability* Pokemod::abilityById(const int id) const throw(IndexException) { return ability(abilityIndex(id)); } Ability* Pokemod::abilityById(const int id) throw(IndexException) { return ability(abilityIndex(id)); } int Pokemod::abilityIndex(const int id) const { for (int i = 0; i < abilityCount(); ++i) { if (m_abilities[i]->id() == id) return i; } return INT_MAX; } int Pokemod::abilityCount() const { return m_abilities.size(); } Ability* Pokemod::newAbility() { m_abilities.append(new Ability(this, newAbilityId())); return m_abilities[abilityCount() - 1]; } Ability* Pokemod::newAbility(const QDomElement& xml) { m_abilities.append(new Ability(this, xml, newAbilityId())); return m_abilities[abilityCount() - 1]; } Ability* Pokemod::newAbility(const Ability& ability) { m_abilities.append(new Ability(this, ability, newAbilityId())); return m_abilities[abilityCount() - 1]; } void Pokemod::deleteAbility(const int index) throw(IndexException) { if (abilityCount() <= index) error("ability"); delete m_abilities[index]; m_abilities.removeAt(index); } void Pokemod::deleteAbilityById(const int id) throw(IndexException) { deleteAbility(abilityIndex(id)); } int Pokemod::newAbilityId() const { int i = 0; while ((i < abilityCount()) && (abilityIndex(i) != INT_MAX)) ++i; return i; } const Author* Pokemod::author(const int index) const throw(IndexException) { if (authorCount() <= index) error("author"); return m_authors.at(index); } Author* Pokemod::author(const int index) throw(IndexException) { if (authorCount() <= index) error("author"); return m_authors[index]; } const Author* Pokemod::authorById(const int id) const throw(IndexException) { return author(authorIndex(id)); } Author* Pokemod::authorById(const int id) throw(IndexException) { return author(authorIndex(id)); } int Pokemod::authorIndex(const int id) const { for (int i = 0; i < authorCount(); ++i) { if (m_authors[i]->id() == id) return i; } return INT_MAX; } int Pokemod::authorCount() const { return m_authors.size(); } Author* Pokemod::newAuthor() { m_authors.append(new Author(this, newAuthorId())); return m_authors[authorCount() - 1]; } Author* Pokemod::newAuthor(const QDomElement& xml) { m_authors.append(new Author(this, xml, newAuthorId())); return m_authors[authorCount() - 1]; } Author* Pokemod::newAuthor(const Author& author) { m_authors.append(new Author(this, author, newAuthorId())); return m_authors[authorCount() - 1]; } void Pokemod::deleteAuthor(const int index) throw(IndexException) { if (authorCount() <= index) error("author"); delete m_authors[index]; m_authors.removeAt(index); } void Pokemod::deleteAuthorById(const int id) throw(IndexException) { deleteAuthor(authorIndex(id)); } int Pokemod::newAuthorId() const { int i = 0; while ((i < authorCount()) && (authorIndex(i) != INT_MAX)) ++i; return i; } const Badge* Pokemod::badge(const int index) const throw(IndexException) { if (badgeCount() <= index) error("badge"); return m_badges.at(index); } Badge* Pokemod::badge(const int index) throw(IndexException) { if (badgeCount() <= index) error("badge"); return m_badges[index]; } const Badge* Pokemod::badgeById(const int id) const throw(IndexException) { return badge(badgeIndex(id)); } Badge* Pokemod::badgeById(const int id) throw(IndexException) { return badge(badgeIndex(id)); } int Pokemod::badgeIndex(const int id) const { for (int i = 0; i < badgeCount(); ++i) { if (m_badges[i]->id() == id) return i; } return INT_MAX; } int Pokemod::badgeCount() const { return m_badges.size(); } Badge* Pokemod::newBadge() { m_badges.append(new Badge(this, newBadgeId())); return m_badges[badgeCount() - 1]; } Badge* Pokemod::newBadge(const QDomElement& xml) { m_badges.append(new Badge(this, xml, newBadgeId())); return m_badges[badgeCount() - 1]; } Badge* Pokemod::newBadge(const Badge& badge) { m_badges.append(new Badge(this, badge, newBadgeId())); return m_badges[badgeCount() - 1]; } void Pokemod::deleteBadge(const int index) throw(IndexException) { if (badgeCount() <= index) error("badge"); delete m_badges[index]; m_badges.removeAt(index); } void Pokemod::deleteBadgeById(const int id) throw(IndexException) { deleteBadge(badgeIndex(id)); } int Pokemod::newBadgeId() const { int i = 0; while ((i < badgeCount()) && (badgeIndex(i) != INT_MAX)) ++i; return i; } const CoinList* Pokemod::coinList(const int index) const throw(IndexException) { if (coinListCount() <= index) error("coin list"); return m_coinLists.at(index); } CoinList* Pokemod::coinList(const int index) throw(IndexException) { if (coinListCount() <= index) error("coin list"); return m_coinLists[index]; } const CoinList* Pokemod::coinListById(const int id) const throw(IndexException) { return coinList(coinListIndex(id)); } CoinList* Pokemod::coinListById(const int id) throw(IndexException) { return coinList(coinListIndex(id)); } int Pokemod::coinListIndex(const int id) const { for (int i = 0; i < coinListCount(); ++i) { if (m_coinLists[i]->id() == id) return i; } return INT_MAX; } int Pokemod::coinListCount() const { return m_coinLists.size(); } CoinList* Pokemod::newCoinList() { m_coinLists.append(new CoinList(this, newCoinListId())); return m_coinLists[coinListCount() - 1]; } CoinList* Pokemod::newCoinList(const QDomElement& xml) { m_coinLists.append(new CoinList(this, xml, newCoinListId())); return m_coinLists[coinListCount() - 1]; } CoinList* Pokemod::newCoinList(const CoinList& coinList) { m_coinLists.append(new CoinList(this, coinList, newCoinListId())); return m_coinLists[coinListCount() - 1]; } void Pokemod::deleteCoinList(const int index) throw(IndexException) { if (coinListCount() <= index) error("coin list"); delete m_coinLists[index]; m_coinLists.removeAt(index); } void Pokemod::deleteCoinListById(const int id) throw(IndexException) { deleteCoinList(coinListIndex(id)); } int Pokemod::newCoinListId() const { int i = 0; while ((i < coinListCount()) && (coinListIndex(i) != INT_MAX)) ++i; return i; } const Dialog* Pokemod::dialog(const int index) const throw(IndexException) { if (dialogCount() <= index) error("dialog"); return m_dialogs.at(index); } Dialog* Pokemod::dialog(const int index) throw(IndexException) { if (dialogCount() <= index) error("dialog"); return m_dialogs[index]; } const Dialog* Pokemod::dialogById(const int id) const throw(IndexException) { return dialog(dialogIndex(id)); } Dialog* Pokemod::dialogById(const int id) throw(IndexException) { return dialog(dialogIndex(id)); } int Pokemod::dialogIndex(const int id) const { for (int i = 0; i < dialogCount(); ++i) { if (m_dialogs[i]->id() == id) return i; } return INT_MAX; } int Pokemod::dialogCount() const { return m_dialogs.size(); } Dialog* Pokemod::newDialog() { m_dialogs.append(new Dialog(this, newDialogId())); return m_dialogs[dialogCount() - 1]; } Dialog* Pokemod::newDialog(const QDomElement& xml) { m_dialogs.append(new Dialog(this, xml, newDialogId())); return m_dialogs[dialogCount() - 1]; } Dialog* Pokemod::newDialog(const Dialog& dialog) { m_dialogs.append(new Dialog(this, dialog, newDialogId())); return m_dialogs[dialogCount() - 1]; } void Pokemod::deleteDialog(const int index) throw(IndexException) { if (dialogCount() <= index) error("dialog"); delete m_dialogs[index]; m_dialogs.removeAt(index); } void Pokemod::deleteDialogById(const int id) throw(IndexException) { deleteDialog(dialogIndex(id)); } int Pokemod::newDialogId() const { int i = 0; while ((i < dialogCount()) && (dialogIndex(i) != INT_MAX)) ++i; return i; } const EggGroup* Pokemod::eggGroup(const int index) const throw(IndexException) { if (eggGroupCount() <= index) error("egg group"); return m_eggGroups.at(index); } EggGroup* Pokemod::eggGroup(const int index) throw(IndexException) { if (eggGroupCount() <= index) error("egg group"); return m_eggGroups[index]; } const EggGroup* Pokemod::eggGroupById(const int id) const throw(IndexException) { return eggGroup(eggGroupIndex(id)); } EggGroup* Pokemod::eggGroupById(const int id) throw(IndexException) { return eggGroup(eggGroupIndex(id)); } int Pokemod::eggGroupIndex(const int id) const { for (int i = 0; i < eggGroupCount(); ++i) { if (m_eggGroups[i]->id() == id) return i; } return INT_MAX; } int Pokemod::eggGroupCount() const { return m_eggGroups.size(); } EggGroup* Pokemod::newEggGroup() { m_eggGroups.append(new EggGroup(this, newEggGroupId())); return m_eggGroups[eggGroupCount() - 1]; } EggGroup* Pokemod::newEggGroup(const QDomElement& xml) { m_eggGroups.append(new EggGroup(this, xml, newEggGroupId())); return m_eggGroups[eggGroupCount() - 1]; } EggGroup* Pokemod::newEggGroup(const EggGroup& eggGroup) { m_eggGroups.append(new EggGroup(this, eggGroup, newEggGroupId())); return m_eggGroups[eggGroupCount() - 1]; } void Pokemod::deleteEggGroup(const int index) throw(IndexException) { if (eggGroupCount() <= index) error("egg group"); delete m_eggGroups[index]; m_eggGroups.removeAt(index); } void Pokemod::deleteEggGroupById(const int id) throw(IndexException) { deleteEggGroup(eggGroupIndex(id)); } int Pokemod::newEggGroupId() const { int i = 0; while ((i < eggGroupCount()) && (eggGroupIndex(i) != INT_MAX)) ++i; return i; } const Item* Pokemod::item(const int index) const throw(IndexException) { if (itemCount() <= index) error("item"); return m_items.at(index); } Item* Pokemod::item(const int index) throw(IndexException) { if (itemCount() <= index) error("item"); return m_items[index]; } const Item* Pokemod::itemById(const int id) const throw(IndexException) { return item(itemIndex(id)); } Item* Pokemod::itemById(const int id) throw(IndexException) { return item(itemIndex(id)); } int Pokemod::itemIndex(const int id) const { for (int i = 0; i < itemCount(); ++i) { if (m_items[i]->id() == id) return i; } return INT_MAX; } int Pokemod::itemCount() const { return m_items.size(); } Item* Pokemod::newItem() { m_items.append(new Item(this, newItemId())); return m_items[itemCount() - 1]; } Item* Pokemod::newItem(const QDomElement& xml) { m_items.append(new Item(this, xml, newItemId())); return m_items[itemCount() - 1]; } Item* Pokemod::newItem(const Item& item) { m_items.append(new Item(this, item, newItemId())); return m_items[itemCount() - 1]; } void Pokemod::deleteItem(const int index) throw(IndexException) { if (itemCount() <= index) error("item"); delete m_items[index]; m_items.removeAt(index); } void Pokemod::deleteItemById(const int id) throw(IndexException) { deleteItem(itemIndex(id)); } int Pokemod::newItemId() const { int i = 0; for (; (i < itemCount()) && (itemIndex(i) != INT_MAX); ++i) ; return i; } const ItemType* Pokemod::itemType(const int index) const throw(IndexException) { if (itemTypeCount() <= index) error("item type"); return m_itemTypes.at(index); } ItemType* Pokemod::itemType(const int index) throw(IndexException) { if (itemTypeCount() <= index) error("item type"); return m_itemTypes[index]; } const ItemType* Pokemod::itemTypeById(const int id) const throw(IndexException) { return itemType(itemTypeIndex(id)); } ItemType* Pokemod::itemTypeById(const int id) throw(IndexException) { return itemType(itemTypeIndex(id)); } int Pokemod::itemTypeIndex(const int id) const { for (int i = 0; i < itemTypeCount(); ++i) { if (m_itemTypes[i]->id() == id) return i; } return INT_MAX; } int Pokemod::itemTypeCount() const { return m_itemTypes.size(); } ItemType* Pokemod::newItemType() { m_itemTypes.append(new ItemType(this, newItemTypeId())); return m_itemTypes[itemTypeCount() - 1]; } ItemType* Pokemod::newItemType(const QDomElement& xml) { m_itemTypes.append(new ItemType(this, xml, newItemTypeId())); return m_itemTypes[itemTypeCount() - 1]; } ItemType* Pokemod::newItemType(const ItemType& itemType) { m_itemTypes.append(new ItemType(this, itemType, newItemTypeId())); return m_itemTypes[itemTypeCount() - 1]; } void Pokemod::deleteItemType(const int index) throw(IndexException) { if (itemTypeCount() <= index) error("item type"); delete m_itemTypes[index]; m_itemTypes.removeAt(index); } void Pokemod::deleteItemTypeById(const int id) throw(IndexException) { deleteItemType(itemTypeIndex(id)); } int Pokemod::newItemTypeId() const { int i = 0; while ((i < itemTypeCount()) && (itemTypeIndex(i) != INT_MAX)) ++i; return i; } const Map* Pokemod::map(const int index) const throw(IndexException) { if (mapCount() <= index) error("map"); return m_maps.at(index); } Map* Pokemod::map(const int index) throw(IndexException) { if (mapCount() <= index) error("map"); return m_maps[index]; } const Map* Pokemod::mapById(const int id) const throw(IndexException) { return map(mapIndex(id)); } Map* Pokemod::mapById(const int id) throw(IndexException) { return map(mapIndex(id)); } int Pokemod::mapIndex(const int id) const { for (int i = 0; i < mapCount(); ++i) { if (m_maps[i]->id() == id) return i; } return INT_MAX; } int Pokemod::mapCount() const { return m_maps.size(); } Map* Pokemod::newMap() { m_maps.append(new Map(this, newMapId())); return m_maps[mapCount() - 1]; } Map* Pokemod::newMap(const QDomElement& xml) { m_maps.append(new Map(this, xml, newMapId())); return m_maps[mapCount() - 1]; } Map* Pokemod::newMap(const Map& map) { m_maps.append(new Map(this, map, newMapId())); return m_maps[mapCount() - 1]; } void Pokemod::deleteMap(const int index) throw(IndexException) { if (mapCount() <= index) error("map"); delete m_maps[index]; m_maps.removeAt(index); } void Pokemod::deleteMapById(const int id) throw(IndexException) { deleteMap(mapIndex(id)); } int Pokemod::newMapId() const { int i = 0; while ((i < mapCount()) && (mapIndex(i) != INT_MAX)) ++i; return i; } const Move* Pokemod::move(const int index) const throw(IndexException) { if (moveCount() <= index) error("move"); return m_moves.at(index); } Move* Pokemod::move(const int index) throw(IndexException) { if (moveCount() <= index) error("move"); return m_moves[index]; } const Move* Pokemod::moveById(const int id) const throw(IndexException) { return move(moveIndex(id)); } Move* Pokemod::moveById(const int id) throw(IndexException) { return move(moveIndex(id)); } int Pokemod::moveIndex(const int id) const { for (int i = 0; i < moveCount(); ++i) { if (m_moves[i]->id() == id) return i; } return INT_MAX; } int Pokemod::moveCount() const { return m_moves.size(); } Move* Pokemod::newMove() { m_moves.append(new Move(this, newMoveId())); return m_moves[moveCount() - 1]; } Move* Pokemod::newMove(const QDomElement& xml) { m_moves.append(new Move(this, xml, newMoveId())); return m_moves[moveCount() - 1]; } Move* Pokemod::newMove(const Move& move) { m_moves.append(new Move(this, move, newMoveId())); return m_moves[moveCount() - 1]; } void Pokemod::deleteMove(const int index) throw(IndexException) { if (moveCount() <= index) error("move"); delete m_moves[index]; m_moves.removeAt(index); } void Pokemod::deleteMoveById(const int id) throw(IndexException) { deleteMove(moveIndex(id)); } int Pokemod::newMoveId() const { int i = 0; while ((i < moveCount()) && (moveIndex(i) != INT_MAX)) ++i; return i; } const Nature* Pokemod::nature(const int index) const throw(IndexException) { if (natureCount() <= index) error("nature"); return m_natures.at(index); } Nature* Pokemod::nature(const int index) throw(IndexException) { if (natureCount() <= index) error("nature"); return m_natures[index]; } const Nature* Pokemod::natureById(const int id) const throw(IndexException) { return nature(natureIndex(id)); } Nature* Pokemod::natureById(const int id) throw(IndexException) { return nature(natureIndex(id)); } int Pokemod::natureIndex(const int id) const { for (int i = 0; i < natureCount(); ++i) { if (m_natures[i]->id() == id) return i; } return INT_MAX; } int Pokemod::natureCount() const { return m_natures.size(); } Nature* Pokemod::newNature() { m_natures.append(new Nature(this, newNatureId())); return m_natures[natureCount() - 1]; } Nature* Pokemod::newNature(const QDomElement& xml) { m_natures.append(new Nature(this, xml, newNatureId())); return m_natures[natureCount() - 1]; } Nature* Pokemod::newNature(const Nature& nature) { m_natures.append(new Nature(this, nature, newNatureId())); return m_natures[natureCount() - 1]; } void Pokemod::deleteNature(const int index) throw(IndexException) { if (natureCount() <= index) error("nature"); delete m_natures[index]; m_natures.removeAt(index); } void Pokemod::deleteNatureById(const int id) throw(IndexException) { deleteNature(natureIndex(id)); } int Pokemod::newNatureId() const { int i = 0; while ((i < natureCount()) && (natureIndex(i) != INT_MAX)) ++i; return i; } const Species* Pokemod::species(const int index) const throw(IndexException) { if (speciesCount() <= index) error("species"); return m_species.at(index); } Species* Pokemod::species(const int index) throw(IndexException) { if (speciesCount() <= index) error("species"); return m_species[index]; } const Species* Pokemod::speciesById(const int id) const throw(IndexException) { return species(speciesIndex(id)); } Species* Pokemod::speciesById(const int id) throw(IndexException) { return species(speciesIndex(id)); } int Pokemod::speciesIndex(const int id) const { for (int i = 0; i < speciesCount(); ++i) { if (m_species[i]->id() == id) return i; } return INT_MAX; } int Pokemod::speciesCount() const { return m_species.size(); } Species* Pokemod::newSpecies() { m_species.append(new Species(this, newSpeciesId())); return m_species[speciesCount() - 1]; } Species* Pokemod::newSpecies(const QDomElement& xml) { m_species.append(new Species(this, xml, newSpeciesId())); return m_species[speciesCount() - 1]; } Species* Pokemod::newSpecies(const Species& species) { m_species.append(new Species(this, species, newSpeciesId())); return m_species[speciesCount() - 1]; } void Pokemod::deleteSpecies(const int index) throw(IndexException) { if (speciesCount() <= index) error("species"); delete m_species[index]; m_species.removeAt(index); } void Pokemod::deleteSpeciesById(const int id) throw(IndexException) { deleteSpecies(speciesIndex(id)); } int Pokemod::newSpeciesId() const { int i = 0; while ((i < speciesCount()) && (speciesIndex(i) != INT_MAX)) ++i; return i; } const Store* Pokemod::store(const int index) const throw(IndexException) { if (storeCount() <= index) error("store"); return m_stores.at(index); } Store* Pokemod::store(const int index) throw(IndexException) { if (storeCount() <= index) error("store"); return m_stores[index]; } const Store* Pokemod::storeById(const int id) const throw(IndexException) { return store(storeIndex(id)); } Store* Pokemod::storeById(const int id) throw(IndexException) { return store(storeIndex(id)); } int Pokemod::storeIndex(const int id) const { for (int i = 0; i < storeCount(); ++i) { if (m_stores[i]->id() == id) return i; } return INT_MAX; } int Pokemod::storeCount() const { return m_stores.size(); } Store* Pokemod::newStore() { m_stores.append(new Store(this, newStoreId())); return m_stores[storeCount() - 1]; } Store* Pokemod::newStore(const QDomElement& xml) { m_stores.append(new Store(this, xml, newStoreId())); return m_stores[storeCount() - 1]; } Store* Pokemod::newStore(const Store& store) { m_stores.append(new Store(this, store, newStoreId())); return m_stores[storeCount() - 1]; } void Pokemod::deleteStore(const int index) throw(IndexException) { if (storeCount() <= index) error("store"); delete m_stores[index]; m_stores.removeAt(index); } void Pokemod::deleteStoreById(const int id) throw(IndexException) { deleteStore(storeIndex(id)); } int Pokemod::newStoreId() const { int i = 0; while ((i < storeCount()) && (storeIndex(i) != INT_MAX)) ++i; return i; } const Tile* Pokemod::tile(const int index) const throw(IndexException) { if (tileCount() <= index) error("tile"); return m_tiles.at(index); } Tile* Pokemod::tile(const int index) throw(IndexException) { if (tileCount() <= index) error("tile"); return m_tiles[index]; } const Tile* Pokemod::tileById(const int id) const throw(IndexException) { return tile(tileIndex(id)); } Tile* Pokemod::tileById(const int id) throw(IndexException) { return tile(tileIndex(id)); } int Pokemod::tileIndex(const int id) const { for (int i = 0; i < tileCount(); ++i) { if (m_tiles[i]->id() == id) return i; } return INT_MAX; } int Pokemod::tileCount() const { return m_tiles.size(); } Tile* Pokemod::newTile() { m_tiles.append(new Tile(this, newTileId())); return m_tiles[tileCount() - 1]; } Tile* Pokemod::newTile(const QDomElement& xml) { m_tiles.append(new Tile(this, xml, newTileId())); return m_tiles[tileCount() - 1]; } Tile* Pokemod::newTile(const Tile& tile) { m_tiles.append(new Tile(this, tile, newTileId())); return m_tiles[tileCount() - 1]; } void Pokemod::deleteTile(const int index) throw(IndexException) { if (tileCount() <= index) error("tile"); delete m_tiles[index]; m_tiles.removeAt(index); } void Pokemod::deleteTileById(const int id) throw(IndexException) { deleteTile(tileIndex(id)); } int Pokemod::newTileId() const { int i = 0; while ((i < tileCount()) && (tileIndex(i) != INT_MAX)) ++i; return i; } const Time* Pokemod::time(const int index) const throw(IndexException) { if (timeCount() <= index) error("time"); return m_times.at(index); } Time* Pokemod::time(const int i) throw(IndexException) { if (timeCount() <= i) error("time"); return m_times[i]; } const Time* Pokemod::timeById(const int id) const throw(IndexException) { return time(timeIndex(id)); } Time* Pokemod::timeById(const int id) throw(IndexException) { return time(timeIndex(id)); } int Pokemod::timeIndex(const int id) const { for (int i = 0; i < timeCount(); ++i) { if (m_times[i]->id() == id) return i; } return INT_MAX; } int Pokemod::timeCount() const { return m_times.size(); } Time* Pokemod::newTime() { m_times.append(new Time(this, newTimeId())); return m_times[timeCount() - 1]; } Time* Pokemod::newTime(const QDomElement& xml) { m_times.append(new Time(this, xml, newTimeId())); return m_times[timeCount() - 1]; } Time* Pokemod::newTime(const Time& time) { m_times.append(new Time(this, time, newTimeId())); return m_times[timeCount() - 1]; } void Pokemod::deleteTime(const int index) throw(IndexException) { if (timeCount() <= index) error("time"); delete m_times[index]; m_times.removeAt(index); } void Pokemod::deleteTimeById(const int id) throw(IndexException) { deleteTime(timeIndex(id)); } int Pokemod::newTimeId() const { int i = 0; while ((i < timeCount()) && (timeIndex(i) != INT_MAX)) ++i; return i; } const Trainer* Pokemod::trainer(const int index) const throw(IndexException) { if (trainerCount() <= index) error("trainer"); return m_trainers.at(index); } Trainer* Pokemod::trainer(const int index) throw(IndexException) { if (trainerCount() <= index) error("trainer"); return m_trainers[index]; } const Trainer* Pokemod::trainerById(const int id) const throw(IndexException) { return trainer(trainerIndex(id)); } Trainer* Pokemod::trainerById(const int id) throw(IndexException) { return trainer(trainerIndex(id)); } int Pokemod::trainerIndex(const int id) const { for (int i = 0; i < trainerCount(); ++i) { if (m_trainers[i]->id() == id) return i; } return INT_MAX; } int Pokemod::trainerCount() const { return m_trainers.size(); } Trainer* Pokemod::newTrainer() { m_trainers.append(new Trainer(this, newTrainerId())); return m_trainers[trainerCount() - 1]; } Trainer* Pokemod::newTrainer(const QDomElement& xml) { m_trainers.append(new Trainer(this, xml, newTrainerId())); return m_trainers[trainerCount() - 1]; } Trainer* Pokemod::newTrainer(const Trainer& trainer) { m_trainers.append(new Trainer(this, trainer, newTrainerId())); return m_trainers[trainerCount() - 1]; } void Pokemod::deleteTrainer(const int index) throw(IndexException) { if (trainerCount() <= index) error("trainer"); delete m_trainers[index]; m_trainers.removeAt(index); } void Pokemod::deleteTrainerById(const int id) throw(IndexException) { deleteTrainer(trainerIndex(id)); } int Pokemod::newTrainerId() const { int i = 0; while ((i < trainerCount()) && (trainerIndex(i) != INT_MAX)) ++i; return i; } const Type* Pokemod::type(const int index) const throw(IndexException) { if (typeCount() <= index) error("type"); return m_types.at(index); } Type* Pokemod::type(const int index) throw(IndexException) { if (typeCount() <= index) error("type"); return m_types[index]; } const Type* Pokemod::typeById(const int id) const throw(IndexException) { return type(typeIndex(id)); } Type* Pokemod::typeById(const int id) throw(IndexException) { return type(typeIndex(id)); } int Pokemod::typeIndex(const int id) const { for (int i = 0; i < typeCount(); ++i) { if (m_types[i]->id() == id) return i; } return INT_MAX; } int Pokemod::typeCount() const { return m_types.size(); } Type* Pokemod::newType() { int i; m_types.append(new Type(this, i = newTypeId())); m_typeChart.addColumn(Frac(1, 1)); m_typeChart.addRow(Frac(1, 1)); return m_types[typeCount() - 1]; } Type* Pokemod::newType(const QDomElement& xml) { int i; m_types.append(new Type(this, xml, i = newTypeId())); m_typeChart.addColumn(Frac(1, 1)); m_typeChart.addRow(Frac(1, 1)); return m_types[typeCount() - 1]; } Type* Pokemod::newType(const Type& type) { m_types.append(new Type(this, type, newTypeId())); m_typeChart.addColumn(Frac(1, 1)); m_typeChart.addRow(Frac(1, 1)); return m_types[typeCount() - 1]; } void Pokemod::deleteType(const int index) throw(IndexException) { if (typeCount() <= index) error("type"); delete m_types[index]; m_typeChart.deleteColumn(index); m_typeChart.deleteRow(index); m_types.removeAt(index); } void Pokemod::deleteTypeById(const int id) throw(IndexException) { deleteType(typeIndex(id)); } int Pokemod::newTypeId() const { int i = 0; while ((i < typeCount()) && (typeIndex(i) != INT_MAX)) ++i; return i; } Pokemod& Pokemod::operator=(const Pokemod& rhs) { if (this == &rhs) return *this; clear(); COPY(title); COPY(version); COPY(description); COPY(startMap); COPY(startWarp); COPY(superPCUname); COPY(superPCPasswd); COPY(typeChart); COPY(rules); COPY_SUB(Ability, abilities); COPY_SUB(Author, authors); COPY_SUB(Badge, badges); COPY_SUB(CoinList, coinLists); COPY_SUB(Dialog, dialogs); COPY_SUB(EggGroup, eggGroups); COPY_SUB(Item, items); COPY_SUB(ItemType, itemTypes); COPY_SUB(Map, maps); COPY_SUB(Move, moves); COPY_SUB(Nature, natures); COPY_SUB(Species, species); COPY_SUB(Store, stores); COPY_SUB(Tile, tiles); COPY_SUB(Time, times); COPY_SUB(Trainer, trainers); COPY_SUB(Type, types); return *this; }