summaryrefslogtreecommitdiffstats
path: root/sigmod/Game.cpp
diff options
context:
space:
mode:
authorBen Boeckel <MathStuf@gmail.com>2009-02-24 13:34:47 -0500
committerBen Boeckel <MathStuf@gmail.com>2009-02-24 13:34:47 -0500
commitecfd6c40473a9eabaa1fd7d8c343fe5e5bb195c3 (patch)
tree78058197c6e222a1f5e53874fcf66af2b4887980 /sigmod/Game.cpp
parent97fac7d7b30058574dc15d7c18382f104bafd833 (diff)
downloadsigen-ecfd6c40473a9eabaa1fd7d8c343fe5e5bb195c3.tar.gz
sigen-ecfd6c40473a9eabaa1fd7d8c343fe5e5bb195c3.tar.xz
sigen-ecfd6c40473a9eabaa1fd7d8c343fe5e5bb195c3.zip
Rename Sigmod::Sigmod to Sigmod::Game so that the identifiers don't clash when using namespace Sigmod
Diffstat (limited to 'sigmod/Game.cpp')
-rw-r--r--sigmod/Game.cpp564
1 files changed, 564 insertions, 0 deletions
diff --git a/sigmod/Game.cpp b/sigmod/Game.cpp
new file mode 100644
index 00000000..8a829be9
--- /dev/null
+++ b/sigmod/Game.cpp
@@ -0,0 +1,564 @@
+/*
+ * Copyright 2007-2009 Ben Boeckel <MathStuf@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+// Header include
+#include "Sigmod.h"
+
+// Sigmod includes
+#include "Ability.h"
+#include "Author.h"
+#include "Badge.h"
+#include "CoinList.h"
+#include "EggGroup.h"
+#include "GlobalScript.h"
+#include "Item.h"
+#include "ItemType.h"
+#include "Macros.h"
+#include "Map.h"
+#include "Move.h"
+#include "Nature.h"
+#include "Rules.h"
+#include "Skin.h"
+#include "Sound.h"
+#include "Species.h"
+#include "Sprite.h"
+#include "Status.h"
+#include "Store.h"
+#include "Tile.h"
+#include "Time.h"
+#include "Trainer.h"
+#include "Type.h"
+#include "Weather.h"
+
+// Qt includes
+#include <QtCore/QSet>
+
+using namespace Sigcore;
+using namespace Sigmod;
+
+Sigmod::Sigmod() :
+ Object(NULL, 0),
+ m_title(""),
+ m_version(""),
+ m_description(""),
+ m_singlePlayer(true),
+ m_startScript("", ""),
+ m_typechart(0, 0),
+ m_rules(new Rules(this))
+{
+}
+
+Sigmod::Sigmod(const Sigmod& sigmod) :
+ Object(NULL, 0),
+ m_rules(new Rules(this))
+{
+ *this = sigmod;
+}
+
+Sigmod::Sigmod(const QDomElement& xml) :
+ Object(NULL, 0),
+ m_rules(new Rules(this))
+{
+ load(xml);
+}
+
+Sigmod::~Sigmod()
+{
+ delete m_rules;
+ clear();
+}
+
+void Sigmod::validate()
+{
+ TEST_BEGIN();
+ if (m_title.isEmpty())
+ emit(error("Title is empty"));
+ if (m_version.isEmpty())
+ emit(error("Version is empty"));
+ if (m_description.isEmpty())
+ emit(warning("Description is empty"));
+ if ((m_typechart.width() != typeCount()) || (m_typechart.height() != typeCount()))
+ emit(error("Type chart is invalid"));
+ TEST_CHILD(m_rules);
+ QSet<int> idChecker;
+ QSet<QString> nameChecker;
+ QSet<int> timeChecker;
+ if (abilityCount() < m_rules->maxAbilities())
+ emit(error("There are too few abilities"));
+ TEST_SUB_BEGIN(Ability, abilities);
+ TEST_SUB("ability", id);
+ TEST_SUB("ability", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!authorCount())
+ emit(error("There are no authors"));
+ TEST_SUB_BEGIN(Author, authors);
+ TEST_SUB("author", id);
+ TEST_SUB("author", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!badgeCount())
+ emit(error("There are no badges"));
+ TEST_SUB_BEGIN(Badge, badges);
+ TEST_SUB("badge", id);
+ TEST_SUB("badge", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!coinListCount())
+ emit(warning("There are no coin lists"));
+ TEST_SUB_BEGIN(CoinList, coinLists);
+ TEST_SUB("coin list", id);
+ TEST_SUB("coin list", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (m_rules->breedingAllowed())
+ {
+ if (!eggGroupCount())
+ emit(error("There are no egg groups"));
+ TEST_SUB_BEGIN(EggGroup, eggGroups);
+ TEST_SUB("egg group", id);
+ TEST_SUB("egg group", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ }
+ if (!globalScriptCount())
+ emit(warning("There are no global scripts"));
+ TEST_SUB_BEGIN(GlobalScript, globalScripts);
+ TEST_SUB("global script", id);
+ TEST_SUB("global script", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!itemCount())
+ emit(warning("There are no items"));
+ TEST_SUB_BEGIN(Item, items);
+ TEST_SUB("item", id);
+ TEST_SUB("item", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!itemTypeCount() && itemCount())
+ emit(error("There are no item types"));
+ TEST_SUB_BEGIN(ItemType, itemTypes);
+ TEST_SUB("item type", id);
+ TEST_SUB("item type", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!mapCount())
+ emit(error("There are no maps"));
+ TEST_SUB_BEGIN(Map, maps);
+ TEST_SUB("map", id);
+ TEST_SUB("map", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!moveCount())
+ emit(error("There are no moves"));
+ TEST_SUB_BEGIN(Move, moves);
+ TEST_SUB("move", id);
+ TEST_SUB("move", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (natureCount() < m_rules->maxNatures())
+ emit(error("There are too few natures"));
+ TEST_SUB_BEGIN(Nature, natures);
+ TEST_SUB("nature", id);
+ TEST_SUB("nature", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ TEST_SUB_BEGIN(Skin, skins);
+ TEST_SUB("skin", id);
+ TEST_SUB("skin", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!soundCount())
+ emit(warning("There are no sounds"));
+ TEST_SUB_BEGIN(Sound, sounds);
+ TEST_SUB("sound", id);
+ TEST_SUB("sound", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!speciesCount())
+ emit(error("There are no species"));
+ TEST_SUB_BEGIN(Species, species);
+ TEST_SUB("species", id);
+ TEST_SUB("species", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!statusCount())
+ emit(error("There are no status effects"));
+ TEST_SUB_BEGIN(Status, status);
+ TEST_SUB("status", id);
+ TEST_SUB("status", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!storeCount())
+ emit(warning("There are no stores"));
+ TEST_SUB_BEGIN(Store, stores);
+ TEST_SUB("store", id);
+ TEST_SUB("store", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!tileCount())
+ emit(error("There are no tiles"));
+ TEST_SUB_BEGIN(Tile, tiles);
+ TEST_SUB("tile", id);
+ TEST_SUB("tile", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!trainerCount())
+ emit(warning("There are no trainers"));
+ TEST_SUB_BEGIN(Trainer, trainers);
+ TEST_SUB("trainer", id);
+ TEST_SUB("trainer", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!timeCount())
+ emit(error("There are no times"));
+ TEST_SUB_BEGIN(Time, times);
+ TEST_SUB("time", id);
+ TEST_SUB("time", name);
+ if (timeChecker.contains((60 * object->hour()) + object->minute()))
+ emit(error(subclass("time", QString("%1:%2").arg(object->hour(), object->minute()))));
+ timeChecker.insert((60 * object->hour()) + object->minute());
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!typeCount())
+ emit(error("There are no types"));
+ TEST_SUB_BEGIN(Type, types);
+ TEST_SUB("type", id);
+ TEST_SUB("type", name);
+ TEST_SUB_END();
+ idChecker.clear();
+ nameChecker.clear();
+ if (!weatherCount())
+ emit(warning("There are no weathers"));
+ TEST_SUB_BEGIN(Weather, weathers);
+ TEST_SUB("weather", id);
+ TEST_SUB("weather", name);
+ TEST_SUB_END();
+ TEST_END();
+}
+
+void Sigmod::load(const QDomElement& xml)
+{
+ LOAD_BEGIN();
+ LOAD(title);
+ LOAD(version);
+ LOAD(description);
+ LOAD(singlePlayer);
+ LOAD(startScript);
+ m_rules->load(xml.firstChildElement("Rules"));
+ LOAD_SUB(newAbility, Ability);
+ LOAD_SUB(newAuthor, Author);
+ LOAD_SUB(newBadge, Badge);
+ LOAD_SUB(newCoinList, CoinList);
+ LOAD_SUB(newEggGroup, EggGroup);
+ LOAD_SUB(newGlobalScript, GlobalScript);
+ LOAD_SUB(newItem, Item);
+ LOAD_SUB(newItemType, ItemType);
+ LOAD_SUB(newMap, Map);
+ LOAD_SUB(newMove, Move);
+ LOAD_SUB(newNature, Nature);
+ LOAD_SUB(newSkin, Skin);
+ LOAD_SUB(newSound, Sound);
+ LOAD_SUB(newSpecies, Species);
+ LOAD_SUB(newSprite, Sprite);
+ LOAD_SUB(newStatus, Status);
+ LOAD_SUB(newStore, Store);
+ LOAD_SUB(newTile, Tile);
+ LOAD_SUB(newTime, Time);
+ LOAD_SUB(newTrainer, Trainer);
+ LOAD_SUB(newType, Type);
+ LOAD_SUB(newWeather, Weather);
+ LOAD_MATRIX(typechart);
+ m_typechart.resize(typeCount(), typeCount());
+}
+
+QDomElement Sigmod::save() const
+{
+ QDomElement xml = QDomDocument().createElement(className());
+ SAVE(title);
+ SAVE(version);
+ SAVE(description);
+ SAVE(singlePlayer);
+ SAVE(startScript);
+ SAVE_Rules(rules);
+ SAVE_MATRIX(typechart);
+ SAVE_SUB(Ability, abilities);
+ SAVE_SUB(Author, authors);
+ SAVE_SUB(Badge, badges);
+ SAVE_SUB(CoinList, coinLists);
+ SAVE_SUB(EggGroup, eggGroups);
+ SAVE_SUB(GlobalScript, globalScripts);
+ SAVE_SUB(Item, items);
+ SAVE_SUB(ItemType, itemTypes);
+ SAVE_SUB(Map, maps);
+ SAVE_SUB(Move, moves);
+ SAVE_SUB(Nature, natures);
+ SAVE_SUB(Skin, skins);
+ SAVE_SUB(Sound, sounds);
+ SAVE_SUB(Species, species);
+ SAVE_SUB(Sprite, sprites);
+ SAVE_SUB(Status, status);
+ SAVE_SUB(Store, stores);
+ SAVE_SUB(Tile, tiles);
+ SAVE_SUB(Time, times);
+ SAVE_SUB(Trainer, trainers);
+ SAVE_SUB(Type, types);
+ SAVE_SUB(Weather, weathers);
+ return xml;
+}
+
+SETTER(Sigmod, QString&, Title, title)
+SETTER(Sigmod, QString&, Version, version)
+SETTER(Sigmod, QString&, Description, description)
+SETTER(Sigmod, bool, SinglePlayer, singlePlayer)
+SETTER(Sigmod, Script&, StartScript, startScript)
+SETTER_MATRIX(Sigmod, Fraction&, Typechart, typechart, multiplier)
+
+void Sigmod::setRules(const Rules& rules)
+{
+ *m_rules = rules;
+}
+
+void Sigmod::setRules(const QDomElement& xml)
+{
+ m_rules->load(xml);
+}
+
+GETTER(Sigmod, QString, title)
+GETTER(Sigmod, QString, version)
+GETTER(Sigmod, QString, description)
+GETTER(Sigmod, bool, singlePlayer)
+GETTER(Sigmod, Script, startScript)
+
+const Matrix<Fraction>* Sigmod::typechart() const
+{
+ return &m_typechart;
+}
+
+Matrix<Fraction>* Sigmod::typechart()
+{
+ return &m_typechart;
+}
+
+Fraction Sigmod::typechart(const int attack, const int defense) const
+{
+ return m_typechart(attack, defense);
+}
+
+const Rules* Sigmod::rules() const
+{
+ return m_rules;
+}
+
+Rules* Sigmod::rules()
+{
+ return m_rules;
+}
+
+CHECK(Sigmod, QString&, title)
+CHECK(Sigmod, QString&, version)
+CHECK(Sigmod, QString&, description)
+CHECK(Sigmod, bool, singlePlayer)
+CHECK(Sigmod, Script&, startScript)
+CHECK_BOUNDS(Sigmod, Fraction&, typechart, 0, INT_MAX)
+
+SSUBCLASS(Sigmod, Ability, ability, abilities)
+SSUBCLASS(Sigmod, Author, author, authors)
+SSUBCLASS(Sigmod, Badge, badge, badges)
+SSUBCLASS(Sigmod, CoinList, coinList, coinLists)
+SSUBCLASS(Sigmod, EggGroup, eggGroup, eggGroups)
+SSUBCLASS(Sigmod, GlobalScript, globalScript, globalScripts)
+SSUBCLASS(Sigmod, Item, item, items)
+SSUBCLASS(Sigmod, ItemType, itemType, itemTypes)
+SSUBCLASS(Sigmod, Map, map, maps)
+SSUBCLASS(Sigmod, Move, move, moves)
+SSUBCLASS(Sigmod, Nature, nature, natures)
+SSUBCLASS(Sigmod, Skin, skin, skins)
+SSUBCLASS(Sigmod, Sound, sound, sounds)
+SSUBCLASS(Sigmod, Species, species, species)
+SSUBCLASS(Sigmod, Sprite, sprite, sprites)
+SSUBCLASS(Sigmod, Status, status, status)
+SSUBCLASS(Sigmod, Store, store, stores)
+SSUBCLASS(Sigmod, Tile, tile, tiles)
+SSUBCLASS(Sigmod, Time, time, times)
+SSUBCLASS(Sigmod, Trainer, trainer, trainers)
+
+const Sigmod::Type* Sigmod::type(const int index) const
+{
+ if (index < typeCount())
+ return m_types.at(index);
+ return NULL;
+}
+
+Sigmod::Type* Sigmod::type(const int index)
+{
+ if (index < typeCount())
+ return m_types[index];
+ return NULL;
+}
+
+const Sigmod::Type* Sigmod::typeById(const int id) const
+{
+ return type(typeIndex(id));
+}
+
+Sigmod::Type* Sigmod::typeById(const int id)
+{
+ return type(typeIndex(id));
+}
+
+int Sigmod::typeIndex(const int id) const
+{
+ for (int i = 0; i < typeCount(); ++i)
+ {
+ if (m_types[i]->id() == id)
+ return i;
+ }
+ return INT_MAX;
+}
+
+int Sigmod::typeCount() const
+{
+ return m_types.size();
+}
+
+Sigmod::Type* Sigmod::newType()
+{
+ return newType(new Type(this, newTypeId()));
+}
+
+Sigmod::Type* Sigmod::newType(const QDomElement& xml)
+{
+ return newType(new Type(xml, this, newTypeId()));
+}
+
+Sigmod::Type* Sigmod::newType(const Type& type)
+{
+ return newType(new Type(type, this, newTypeId()));
+}
+
+Sigmod::Type* Sigmod::newType(Type* type)
+{
+ m_types.append(type);
+ m_typechart.resize(typeCount(), typeCount(), Sigcore::Fraction(1, 1));
+ return type;
+}
+
+void Sigmod::deleteType(const int index)
+{
+ if (index < typeCount())
+ {
+ delete m_types[index];
+ m_types.removeAt(index);
+ m_typechart.resize(typeCount(), typeCount(), Sigcore::Fraction(1, 1));
+ }
+}
+
+void Sigmod::deleteTypeById(const int id)
+{
+ deleteType(typeIndex(id));
+}
+
+int Sigmod::newTypeId() const
+{
+ int i = 0;
+ while ((i < typeCount()) && (typeIndex(i) != INT_MAX))
+ ++i;
+ return i;
+}
+
+SSUBCLASS(Sigmod, Weather, weather, weathers)
+
+Sigmod::Sigmod& Sigmod::operator=(const Sigmod& rhs)
+{
+ if (this == &rhs)
+ return *this;
+ clear();
+ COPY(title);
+ COPY(version);
+ COPY(description);
+ COPY(singlePlayer);
+ COPY(startScript);
+ COPY(typechart);
+ COPY_Rules(rules);
+ COPY_SUB(Ability, abilities);
+ COPY_SUB(Author, authors);
+ COPY_SUB(Badge, badges);
+ COPY_SUB(CoinList, coinLists);
+ COPY_SUB(EggGroup, eggGroups);
+ COPY_SUB(GlobalScript, globalScripts);
+ COPY_SUB(Item, items);
+ COPY_SUB(ItemType, itemTypes);
+ COPY_SUB(Map, maps);
+ COPY_SUB(Move, moves);
+ COPY_SUB(Nature, natures);
+ COPY_SUB(Skin, skins);
+ COPY_SUB(Sound, sounds);
+ COPY_SUB(Species, species);
+ COPY_SUB(Sprite, sprites);
+ COPY_SUB(Status, status);
+ COPY_SUB(Store, stores);
+ COPY_SUB(Tile, tiles);
+ COPY_SUB(Time, times);
+ COPY_SUB(Trainer, trainers);
+ COPY_SUB(Type, types);
+ COPY_SUB(Weather, weathers);
+ m_typechart.resize(typeCount(), typeCount());
+ return *this;
+}
+
+void Sigmod::clear()
+{
+ SUBCLASS_CLEAR(abilities);
+ SUBCLASS_CLEAR(badges);
+ SUBCLASS_CLEAR(coinLists);
+ SUBCLASS_CLEAR(eggGroups);
+ SUBCLASS_CLEAR(globalScripts);
+ SUBCLASS_CLEAR(items);
+ SUBCLASS_CLEAR(maps);
+ SUBCLASS_CLEAR(moves);
+ SUBCLASS_CLEAR(natures);
+ SUBCLASS_CLEAR(skins);
+ SUBCLASS_CLEAR(sounds);
+ SUBCLASS_CLEAR(species);
+ SUBCLASS_CLEAR(sprites);
+ SUBCLASS_CLEAR(status);
+ SUBCLASS_CLEAR(stores);
+ SUBCLASS_CLEAR(tiles);
+ SUBCLASS_CLEAR(trainers);
+ SUBCLASS_CLEAR(types);
+ SUBCLASS_CLEAR(weathers);
+}