summaryrefslogtreecommitdiffstats
path: root/sigencore/TeamMember.cpp
diff options
context:
space:
mode:
authorBen Boeckel <MathStuf@gmail.com>2009-01-27 22:07:08 -0500
committerBen Boeckel <MathStuf@gmail.com>2009-01-27 22:07:08 -0500
commite04c4922a13ed10e9d6b086eacc299f0c5a05984 (patch)
tree907e109278adbea9ae100feb61e020174033a3e5 /sigencore/TeamMember.cpp
parentd111ea6a931a7120631f6e88e9414cbdb851e0e8 (diff)
downloadsigen-e04c4922a13ed10e9d6b086eacc299f0c5a05984.tar.gz
sigen-e04c4922a13ed10e9d6b086eacc299f0c5a05984.tar.xz
sigen-e04c4922a13ed10e9d6b086eacc299f0c5a05984.zip
Begin migration of core classes to libsigencore
Diffstat (limited to 'sigencore/TeamMember.cpp')
-rw-r--r--sigencore/TeamMember.cpp705
1 files changed, 705 insertions, 0 deletions
diff --git a/sigencore/TeamMember.cpp b/sigencore/TeamMember.cpp
new file mode 100644
index 00000000..55ba656a
--- /dev/null
+++ b/sigencore/TeamMember.cpp
@@ -0,0 +1,705 @@
+/*
+ * Copyright 2007-2008 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 "TeamMember.h"
+
+// Sigbattle includes
+#include "Arena.h"
+#include "Containment.h"
+#include "Player.h"
+
+// Sigscript includes
+#include "../sigscript/AbilityWrapper.h"
+#include "../sigscript/ItemWrapper.h"
+#include "../sigscript/MapTrainerTeamMemberWrapper.h"
+#include "../sigscript/MoveWrapper.h"
+#include "../sigscript/NatureWrapper.h"
+#include "../sigscript/RulesWrapper.h"
+#include "../sigscript/SigmodWrapper.h"
+#include "../sigscript/StatusWrapper.h"
+#include "../sigscript/SpeciesWrapper.h"
+#include "../sigscript/SpeciesMoveWrapper.h"
+
+// Sigcore includes
+#include "../sigcore/Hat.h"
+
+// KDE includes
+#include <kross/core/action.h>
+#include <kross/core/actioncollection.h>
+#include <kross/core/manager.h>
+
+// Qt includes
+#include <QtCore/QUuid>
+
+// C includes
+#include <cmath>
+
+int Sigbattle::actionPriority(TeamMember* teamMember, const TeamMember::Action& action)
+{
+ int priority = INT_MAX;
+ switch (action.first)
+ {
+ case TeamMember::Attack:
+ {
+ QString move = action.second.first.toString();
+ if (teamMember->hasValueOfType<int>(QString("move-priority-%1").arg(move)))
+ {
+ priority = teamMember->valueOfType<int>(QString("move-priority-%1").arg(move));
+ teamMember->removeValue(QString("move-priority-%1").arg(move));
+ }
+ else
+ priority = teamMember->sigmod()->move(move)->priority();
+ break;
+ }
+ case TeamMember::Item:
+ priority = INT_MIN / 3;
+ break;
+ case TeamMember::Switch:
+ priority = INT_MIN / 2;
+ break;
+ case TeamMember::Run:
+ priority = INT_MIN;
+ break;
+ case TeamMember::Skip:
+ priority = INT_MAX - 2;
+ break;
+ case TeamMember::Timeout:
+ priority = INT_MAX;
+ break;
+ case TeamMember::Invalid:
+ priority = INT_MAX - 1;
+ break;
+ }
+ return priority;
+}
+
+Sigbattle::TeamMember::TeamMember(const int speciesId, const QString& name, const int level, Containment* containment, const bool suppressItems) :
+ Sigscript::Config(containment),
+ m_containment(containment),
+ m_id(QUuid::createUuid())
+{
+ makeConnections();
+ setSpecies(sigmod()->species(speciesId));
+ if (name.isEmpty())
+ setName(m_species->name());
+ else
+ setName(name);
+ setLevel(level);
+ if (!suppressItems)
+ initItems();
+ initAbilities();
+ initMoves();
+ initNatures();
+ initStats();
+ if (m_species->genderFactor() <= 1)
+ m_gender = (m_species->genderFactor().poll() ? Male : Female);
+ else
+ m_gender = Genderless;
+ for (int i = 0; i <= Sigmod::ST_SpecialDefense; ++i)
+ m_statExp[i] = 0;
+ if (m_containment->isMutable())
+ {
+ const Sigcore::Script script = m_species->evolution();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* evolution = new Kross::Action(Kross::Manager::self().actionCollection()->collection("evolutions"), QUuid::createUuid().toString());
+ evolution->setInterpreter(script.interpreter());
+ evolution->setCode(script.script().toUtf8());
+ evolution->addObject(this, "owner");
+ evolution->trigger();
+ }
+ }
+ m_currentHp = statValue(Sigmod::ST_HP);
+}
+
+Sigbattle::TeamMember::TeamMember(Sigscript::MapTrainerTeamMemberWrapper* teamMember, Containment* containment) :
+ Sigscript::Config(containment),
+ m_containment(containment),
+ m_id(QUuid::createUuid())
+{
+ makeConnections();
+ setSpecies(teamMember->species());
+ setName(m_species->name());
+ setLevel(teamMember->level());
+ const QMap<Sigscript::ItemWrapper*, int>& itemMap = teamMember->items();
+ QList<Sigscript::ItemWrapper*> items = itemMap.keys();
+ foreach (Sigscript::ItemWrapper* item, items)
+ {
+ for (int i = 0; i < itemMap[item]; ++i)
+ m_items.append(item);
+ }
+ initAbilities(teamMember->abilities());
+ initMoves(teamMember->moves());
+ initNatures(teamMember->natures());
+ initStats();
+ if (m_species->genderFactor() <= 1)
+ m_gender = (m_species->genderFactor().poll() ? Male : Female);
+ else
+ m_gender = Genderless;
+ for (int i = 0; i <= Sigmod::ST_SpecialDefense; ++i)
+ m_statExp[i] = 0;
+ m_currentHp = statValue(Sigmod::ST_HP);
+}
+
+Sigbattle::Containment* Sigbattle::TeamMember::containment() const
+{
+ return m_containment;
+}
+
+QUuid Sigbattle::TeamMember::id() const
+{
+ return m_id;
+}
+
+QString Sigbattle::TeamMember::name() const
+{
+ if (hasValueOfType<QString>("name"))
+ return valueOfType<QString>("name");
+ return m_name;
+}
+
+long long Sigbattle::TeamMember::currentHp() const
+{
+ return m_currentHp;
+}
+
+Sigscript::SpeciesWrapper* Sigbattle::TeamMember::species() const
+{
+ if (hasValueOfType<Sigscript::SpeciesWrapper*>("species"))
+ return valueOfType<Sigscript::SpeciesWrapper*>("species");
+ return m_species;
+}
+
+int Sigbattle::TeamMember::level() const
+{
+ return m_level;
+}
+
+Sigbattle::TeamMember::Gender Sigbattle::TeamMember::gender() const
+{
+ if (hasValueOfType<Gender>("gender"))
+ return valueOfType<Gender>("gender");
+ return m_gender;
+}
+
+long long Sigbattle::TeamMember::levelExperience() const
+{
+ if (hasValueOfType<long long>("levelExperience"))
+ return valueOfType<long long>("levelExperience");
+ return m_levelExp;
+}
+
+int Sigbattle::TeamMember::baseStat(const Sigmod::Stat stat) const
+{
+ if (hasValueOfType<bool>("overrideBaseStats") && valueOfType<bool>("overrideBaseStats"))
+ return species()->baseStat(stat);
+ return m_species->baseStat(stat);
+}
+
+long long Sigbattle::TeamMember::statExperience(const Sigmod::Stat stat) const
+{
+ const QString valueName = QString("statExperience-%1").arg((sigmod()->rules()->specialSplit() ? Sigmod::StatGSCStr : Sigmod::StatRBYStr)[stat]);
+ if (hasValueOfType<long long>(valueName))
+ return valueOfType<long long>(valueName);
+ return m_statExp[stat];
+}
+
+int Sigbattle::TeamMember::dv(const Sigmod::Stat stat) const
+{
+ const QString valueName = QString("dv-%1").arg((sigmod()->rules()->specialSplit() ? Sigmod::StatGSCStr : Sigmod::StatRBYStr)[stat]);
+ if (hasValueOfType<int>(valueName))
+ {
+ const int dv = valueOfType<int>(valueName);
+ if (dv < (sigmod()->rules()->specialDVSplit() ? 32 : 16))
+ return dv;
+ }
+ return m_dv[stat];
+}
+
+long long Sigbattle::TeamMember::statValue(const Sigmod::Stat stat, const long long exp) const
+{
+ long long statValue;
+ if (exp < 0)
+ statValue = statExperience(stat);
+ else
+ statValue = exp;
+ if (!sigmod()->rules()->effortValuesAllowed() && statValue)
+ statValue = sqrt(statValue - 1) + 1;
+ statValue >>= 2;
+ statValue += baseStat(stat) << 1;
+ if (sigmod()->rules()->specialDVSplit())
+ {
+ if (stat == Sigmod::ST_SpecialDefense)
+ statValue += dv(Sigmod::ST_Special) << 1;
+ else
+ statValue += dv(stat) << 1;
+ }
+ else
+ statValue += dv(stat);
+ statValue *= double(m_level) / sigmod()->rules()->maxLevel();
+ if (stat == Sigmod::ST_HP)
+ statValue += 10 + m_level;
+ else
+ {
+ statValue += 5;
+ Sigcore::Fraction multiplier;
+ foreach (Sigscript::NatureWrapper* nature, m_natures)
+ multiplier *= nature->stat(stat);
+ statValue *= multiplier;
+ }
+ return statValue;
+}
+
+long long Sigbattle::TeamMember::calcExp(int level) const
+{
+ if (level < 0)
+ level = m_level;
+ const long long square = level * level;
+ const long long cube = square * level;
+ switch (m_species->growth())
+ {
+ case Sigmod::Species::Fluctuating:
+ if (level <= 15)
+ return cube * ((24 + (level + 1) / 3) / 50.0);
+ else if (level <= 35)
+ return cube * ((14 + level) / 50.0);
+ else if (level <= 100)
+ return cube * ((32 + (level / 2)) / 50.0);
+ // TODO: better way for further growth?
+ else if (level <= 102)
+ return cube * (23 + level) / 75;
+ else
+ return 5 * cube / 3;
+ case Sigmod::Species::Fading:
+ return 6 * cube / 5 - 15 * square + 100 * level - 140;
+ case Sigmod::Species::Slow:
+ return 5 * cube / 4;
+ case Sigmod::Species::Normal:
+ return cube;
+ case Sigmod::Species::Fast:
+ return 4 * cube / 5;
+ case Sigmod::Species::Erratic:
+ {
+ const double p[] = {0.000, 0.008, 0.014};
+ if (level <= 50)
+ return cube * ((100 - level) / 50.0);
+ else if (level <= 68)
+ return cube * ((150 - level) / 100.0);
+ else if (level <= 98)
+ return cube * (1.274 - (level / 3) / 50.0 - p[level % 3]);
+ else if (level <= 100)
+ return cube * ((160 - level) / 100.0);
+ // TODO: better way for further growth?
+ else
+ return 3 * cube / 5;
+ }
+ default:
+ break;
+ }
+ return -1;
+}
+
+bool Sigbattle::TeamMember::canLearnMove(Sigscript::MoveWrapper* move) const
+{
+ for (int i = 0; i < m_species->moveCount(); ++i)
+ {
+ if (move->id() == m_species->move(i)->move()->id())
+ return true;
+ }
+ return false;
+}
+
+long long Sigbattle::TeamMember::timer() const
+{
+ return m_timer;
+}
+
+void Sigbattle::TeamMember::boostLevels(const int levels)
+{
+ if ((m_level + levels) < sigmod()->rules()->maxLevel())
+ {
+ for (int i = 0; i < levels; ++i)
+ setLevel(m_level + 1);
+ }
+}
+
+void Sigbattle::TeamMember::evolveInto(Sigscript::SpeciesWrapper* newSpecies)
+{
+ emit(evolveStart());
+ int oldStats[Sigmod::ST_SpecialDefense - Sigmod::ST_HP + 1] = {};
+ int newStats[Sigmod::ST_SpecialDefense - Sigmod::ST_HP + 1] = {};
+ oldStats[Sigmod::ST_Attack] = statValue(Sigmod::ST_Attack);
+ oldStats[Sigmod::ST_Defense] = statValue(Sigmod::ST_Defense);
+ oldStats[Sigmod::ST_Speed] = statValue(Sigmod::ST_Speed);
+ if (sigmod()->rules()->specialSplit())
+ {
+ oldStats[Sigmod::ST_SpecialAttack] = statValue(Sigmod::ST_SpecialAttack);
+ oldStats[Sigmod::ST_SpecialDefense] = statValue(Sigmod::ST_SpecialDefense);
+ }
+ else
+ oldStats[Sigmod::ST_Special] = statValue(Sigmod::ST_Special);
+ setSpecies(newSpecies);
+ newStats[Sigmod::ST_Attack] = statValue(Sigmod::ST_Attack);
+ newStats[Sigmod::ST_Defense] = statValue(Sigmod::ST_Defense);
+ newStats[Sigmod::ST_Speed] = statValue(Sigmod::ST_Speed);
+ if (sigmod()->rules()->specialSplit())
+ {
+ newStats[Sigmod::ST_SpecialAttack] = statValue(Sigmod::ST_SpecialAttack);
+ newStats[Sigmod::ST_SpecialDefense] = statValue(Sigmod::ST_SpecialDefense);
+ }
+ else
+ newStats[Sigmod::ST_Special] = statValue(Sigmod::ST_Special);
+ if (oldStats[Sigmod::ST_Attack] != newStats[Sigmod::ST_Attack])
+ emit(statChanged(Sigmod::ST_Attack, newStats[Sigmod::ST_Attack]));
+ if (oldStats[Sigmod::ST_Defense] != newStats[Sigmod::ST_Defense])
+ emit(statChanged(Sigmod::ST_Defense, newStats[Sigmod::ST_Defense]));
+ if (oldStats[Sigmod::ST_Speed] != newStats[Sigmod::ST_Speed])
+ emit(statChanged(Sigmod::ST_Speed, newStats[Sigmod::ST_Speed]));
+ if (sigmod()->rules()->specialSplit())
+ {
+ if (oldStats[Sigmod::ST_SpecialAttack] != newStats[Sigmod::ST_SpecialAttack])
+ emit(statChanged(Sigmod::ST_SpecialAttack, newStats[Sigmod::ST_SpecialAttack]));
+ if (oldStats[Sigmod::ST_SpecialDefense] != newStats[Sigmod::ST_SpecialDefense])
+ emit(statChanged(Sigmod::ST_SpecialDefense, newStats[Sigmod::ST_SpecialDefense]));
+ }
+ else
+ {
+ if (oldStats[Sigmod::ST_Special] != newStats[Sigmod::ST_Special])
+ emit(statChanged(Sigmod::ST_Special, newStats[Sigmod::ST_Special]));
+ }
+ emit(evolveEnd());
+}
+
+void Sigbattle::TeamMember::setName(const QString& name)
+{
+ if (m_name != name)
+ {
+ const QString oldName = m_name;
+ m_name = name;
+ emit(nameChanged(oldName, m_name));
+ }
+}
+
+void Sigbattle::TeamMember::cureStatus(Sigscript::StatusWrapper* status)
+{
+ if (m_status.contains(status))
+ {
+ QList<Kross::Action*> actions = m_status.values(status);
+ qDeleteAll(actions);
+ m_status.remove(status);
+ emit(statusCured(status));
+ }
+}
+
+void Sigbattle::TeamMember::giveStatus(Sigscript::StatusWrapper* status)
+{
+ if (!m_status.contains(status))
+ {
+ const Sigcore::Script script = status->worldScript();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* statusAction = new Kross::Action(Kross::Manager::self().actionCollection()->collection("status"), QUuid::createUuid().toString());
+ statusAction->setInterpreter(script.interpreter());
+ statusAction->setCode(script.script().toUtf8());
+ statusAction->addObject(this, "owner");
+ statusAction->trigger();
+ m_status.insert(status, statusAction);
+ emit(statusInflicted(status));
+ }
+ }
+}
+
+void Sigbattle::TeamMember::giveLevelExp(const int exp)
+{
+ if (m_level == sigmod()->rules()->maxLevel())
+ return;
+ const int expNeeded = calcExp(m_level + 1) - calcExp();
+ if (exp < expNeeded)
+ {
+ m_levelExp += exp;
+ emit(expGained(exp));
+ }
+ else
+ {
+ setLevel(m_level + 1);
+ emit(expGained(expNeeded));
+ giveLevelExp(exp - expNeeded);
+ }
+}
+
+void Sigbattle::TeamMember::giveStatExp(const Sigmod::Stat stat, const int exp)
+{
+ const int oldStat = statValue(stat);
+ int expToGive = exp;
+ if (sigmod()->rules()->effortValuesAllowed())
+ {
+ int totalEV = 0;
+ for (int i = 0; i <= Sigmod::ST_SpecialDefense; ++i)
+ totalEV += m_statExp[i];
+ while (expToGive && (totalEV < sigmod()->rules()->maxTotalEV()) && (m_statExp[stat] < sigmod()->rules()->maxEVPerStat()))
+ {
+ --expToGive;
+ ++totalEV;
+ ++m_statExp[stat];
+ }
+ }
+ else
+ {
+ while (expToGive && (m_statExp[stat] < INT_MAX))
+ {
+ --expToGive;
+ ++m_statExp[stat];
+ }
+ }
+ const int newStat = statValue(stat);
+ if (oldStat != newStat)
+ emit(statChanged(stat, newStat));
+}
+
+void Sigbattle::TeamMember::takeItem(Sigscript::ItemWrapper* item)
+{
+ if (m_items.contains(item))
+ {
+ m_items.removeAt(m_items.indexOf(item));
+ emit(itemTaken(item));
+ }
+}
+
+void Sigbattle::TeamMember::giveItem(Sigscript::ItemWrapper* item)
+{
+ if ((m_items.size() < sigmod()->rules()->maxHeldItems()) && checkWeight(item))
+ {
+ m_items.append(item);
+ emit(itemGiven(item));
+ }
+}
+
+void Sigbattle::TeamMember::forgetMove(Sigscript::MoveWrapper* move)
+{
+ if (m_moves.contains(move))
+ {
+ m_moves.removeAll(move);
+ emit(moveForgotten(move));
+ }
+}
+
+void Sigbattle::TeamMember::teachMove(Sigscript::MoveWrapper* move)
+{
+ if (canLearnMove(move))
+ {
+ if (m_moves.size() < sigmod()->rules()->maxMoves())
+ {
+ m_moves.append(move);
+ emit(moveLearned(move));
+ }
+ emit(movesFull(move));
+ }
+ emit(unlearnableMove(move));
+}
+
+Sigbattle::TeamMember::Action Sigbattle::TeamMember::requestAction()
+{
+ Player* player = qobject_cast<Player*>(m_containment);
+ m_lastAction = player ? player->requestAction(this) : Action(Invalid, ActionData());
+ return m_lastAction;
+}
+
+Sigbattle::TeamMember::Action Sigbattle::TeamMember::latestAction() const
+{
+ return m_lastAction;
+ Player* player = qobject_cast<Player*>(m_containment);
+ if (player)
+ return player->requestAction(this);
+ return Action(Invalid, ActionData());
+}
+
+void Sigbattle::TeamMember::makeActive(Arena* arena)
+{
+ m_timer = 0;
+ QList<Sigscript::StatusWrapper*> statuses = m_status.uniqueKeys();
+ foreach (Sigscript::StatusWrapper* status, statuses)
+ {
+ const Sigcore::Script script = status->battleScript();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* action = new Kross::Action(Kross::Manager::self().actionCollection()->collection("status"), QUuid::createUuid().toString());
+ action->setInterpreter(script.interpreter());
+ action->setCode(script.script().toUtf8());
+ action->addObject(arena, "arena");
+ action->addObject(this, "owner");
+ action->trigger();
+ m_statusBattleScripts.append(action);
+ }
+ }
+ QList<Sigscript::AbilityWrapper*> abilities = m_abilities.keys();
+ foreach (Sigscript::AbilityWrapper* ability, abilities)
+ {
+ const Sigcore::Script script = ability->battleScript();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* action = new Kross::Action(Kross::Manager::self().actionCollection()->collection("ability"), QUuid::createUuid().toString());
+ action->setInterpreter(script.interpreter());
+ action->setCode(script.script().toUtf8());
+ action->addObject(arena, "arena");
+ action->addObject(this, "owner");
+ action->trigger();
+ m_abilityBattleScripts.append(action);
+ }
+ }
+}
+
+void Sigbattle::TeamMember::leaveArena()
+{
+ Kross::ActionCollection* collection = Kross::Manager::self().actionCollection()->collection("status");
+ foreach (Kross::Action* action, m_statusBattleScripts)
+ collection->removeAction(action);
+ collection = Kross::Manager::self().actionCollection()->collection("ability");
+ foreach (Kross::Action* action, m_abilityBattleScripts)
+ collection->removeAction(action);
+}
+
+void Sigbattle::TeamMember::advanceTimer(const long long jump)
+{
+ m_timer += jump;
+}
+
+void Sigbattle::TeamMember::writeBack()
+{
+ // TODO: write back all (applicable) differences between config and local storage
+}
+
+Sigscript::SigmodWrapper* Sigbattle::TeamMember::sigmod() const
+{
+ return m_containment->sigmod();
+}
+
+void Sigbattle::TeamMember::setSpecies(Sigscript::SpeciesWrapper* species)
+{
+ m_species = species;
+ emit(speciesChanged(m_species));
+}
+
+void Sigbattle::TeamMember::setLevel(const int level)
+{
+ emit(levelAboutToGrow());
+ m_level = level;
+ emit(levelGrown(level));
+ m_levelExp = calcExp();
+}
+
+void Sigbattle::TeamMember::levelGrown()
+{
+ for (int i = 0; i < m_species->moveCount(); ++i)
+ {
+ Sigscript::SpeciesMoveWrapper* move = m_species->move(i);
+ if (move->level() == m_level)
+ teachMove(move->move());
+ }
+}
+
+bool Sigbattle::TeamMember::checkWeight(const Sigscript::ItemWrapper* item)
+{
+ int totalWeight = item->weight();
+ foreach (Sigscript::ItemWrapper* item, m_items)
+ totalWeight += item->weight();
+ return (totalWeight <= species()->maxHoldWeight());
+}
+
+void Sigbattle::TeamMember::makeConnections()
+{
+ // TODO: make connections that are necessary (watching Config changes mainly)
+}
+
+void Sigbattle::TeamMember::initAbility(Sigscript::AbilityWrapper* ability)
+{
+ const Sigcore::Script script = ability->battleScript();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* action = new Kross::Action(Kross::Manager::self().actionCollection()->collection("ability"), QUuid::createUuid().toString());
+ action->setInterpreter(script.interpreter());
+ action->setCode(script.script().toUtf8());
+ action->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals);
+ action->trigger();
+ m_abilities[ability] = action;
+ }
+}
+
+void Sigbattle::TeamMember::initItems()
+{
+ Sigcore::Hat<Sigscript::ItemWrapper*> hat = m_species->itemHat();
+ for (int i = 0; i < sigmod()->rules()->maxHeldItems(); ++i)
+ {
+ if (m_species->itemChance().poll())
+ {
+ Sigscript::ItemWrapper* item = hat.pick();
+ if (checkWeight(item))
+ m_items.append(item);
+ }
+ }
+}
+
+void Sigbattle::TeamMember::initAbilities(const QList<Sigscript::AbilityWrapper*>& initial)
+{
+ foreach (Sigscript::AbilityWrapper* ability, initial)
+ initAbility(ability);
+ Sigcore::Hat<Sigscript::AbilityWrapper*> hat = m_species->abilityHat();
+ while (m_abilities.size() < sigmod()->rules()->maxAbilities())
+ {
+ Sigscript::AbilityWrapper* ability = hat.takeAndClear();
+ if (!m_abilities.contains(ability))
+ initAbility(ability);
+ }
+}
+
+void Sigbattle::TeamMember::initMoves(const QList<Sigscript::MoveWrapper*>& initial)
+{
+ m_moves = initial;
+ for (int i = 0; (i < m_species->moveCount()) && (m_moves.size() < sigmod()->rules()->maxMoves()); ++i)
+ {
+ Sigscript::SpeciesMoveWrapper* move = m_species->move(i);
+ if (!m_moves.contains(move->move()) && (((move->level() < m_level) && move->level()) || (!m_containment->isMutable() && (move->wild() < m_level))))
+ m_moves.append(move->move());
+ }
+}
+
+void Sigbattle::TeamMember::initNatures(const QList<Sigscript::NatureWrapper*>& initial)
+{
+ m_natures = initial;
+ Sigcore::Hat<Sigscript::NatureWrapper*> hat = sigmod()->natureHat();
+ while (m_natures.size() < sigmod()->rules()->maxNatures())
+ {
+ Sigscript::NatureWrapper* nature = hat.takeAndClear();
+ if (!m_natures.contains(nature))
+ m_natures.append(nature);
+ }
+}
+
+void Sigbattle::TeamMember::initStats()
+{
+ if (sigmod()->rules()->specialDVSplit())
+ {
+ for (int i = Sigmod::ST_HP; i <= Sigmod::ST_SpecialDefense; ++i)
+ m_dv[i] = qrand() & 31;
+ }
+ else
+ {
+ for (int i = Sigmod::ST_Attack; i <= Sigmod::ST_Special; ++i)
+ m_dv[i] = qrand() & 15;
+ m_dv[Sigmod::ST_HP] = ((m_dv[Sigmod::ST_Attack] & 1) << 3) + ((m_dv[Sigmod::ST_Defense] & 1) << 2) + ((m_dv[Sigmod::ST_Speed] & 1) << 1) + (m_dv[Sigmod::ST_Special] & 1);
+ }
+}