summaryrefslogtreecommitdiffstats
path: root/sigencore/Arena.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/Arena.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/Arena.cpp')
-rw-r--r--sigencore/Arena.cpp248
1 files changed, 248 insertions, 0 deletions
diff --git a/sigencore/Arena.cpp b/sigencore/Arena.cpp
new file mode 100644
index 00000000..8a6dc7bd
--- /dev/null
+++ b/sigencore/Arena.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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 "Arena.h"
+
+// Sigbattle includes
+#include "Player.h"
+
+// Sigscript includes
+#include "../sigscript/ItemWrapper.h"
+#include "../sigscript/MoveWrapper.h"
+#include "../sigscript/SigmodWrapper.h"
+#include "../sigscript/SpeciesWrapper.h"
+
+// Sigcore includes
+// #include "../sigcore/Fraction.h"
+#include "../sigcore/Script.h"
+
+// KDE includes
+#include <kross/core/action.h>
+#include <kross/core/actioncollection.h>
+#include <kross/core/manager.h>
+
+// Qt includes
+#include <QtCore/QtConcurrentRun>
+#include <QtCore/QUuid>
+
+Sigbattle::TeamMember::RequestedAction Sigbattle::requestDecision(TeamMember* teamMember)
+{
+ return TeamMember::RequestedAction(teamMember, QtConcurrent::run(decision, teamMember));
+}
+
+Sigbattle::TeamMember::Action Sigbattle::decision(TeamMember* teamMember)
+{
+ return teamMember->requestAction();
+}
+
+Sigbattle::Arena::Arena(Sigscript::SigmodWrapper* sigmod, QSet<Player*> players, const bool isWild, Sigscript::Config* parent) :
+ Sigscript::Config(parent),
+ m_sigmod(sigmod),
+ m_isWild(isWild),
+ m_isOver(false),
+ m_players(players),
+ m_id(QUuid::createUuid())
+{
+ connect(this, SIGNAL(battleEnd()), SLOT(cleanUp()));
+ m_actions = new Kross::ActionCollection(QString("arena-%1").arg(m_id.toString()), Kross::Manager::self().actionCollection());
+ foreach (Player* player, m_players)
+ player->enterArena(this);
+}
+
+Sigbattle::Arena::~Arena()
+{
+ delete m_actions;
+}
+
+QList<Sigbattle::TeamMember*> Sigbattle::Arena::active() const
+{
+ QList<Sigbattle::TeamMember*> active;
+ foreach (Player* player, m_players)
+ active += player->active();
+ return active;
+}
+
+int Sigbattle::Arena::numActiveTeams() const
+{
+ int active = 0;
+ foreach (Player* player, m_players)
+ active += !player->active().isEmpty();
+ return active;
+}
+
+bool Sigbattle::Arena::isOver() const
+{
+ return m_isOver;
+}
+
+Sigscript::SigmodWrapper* Sigbattle::Arena::sigmod() const
+{
+ return m_sigmod;
+}
+
+void Sigbattle::Arena::registerScript(const Sigcore::Script& script)
+{
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* action = new Kross::Action(m_actions, QUuid::createUuid().toString());
+ action->setInterpreter(script.interpreter());
+ action->setCode(script.script().toUtf8());
+ action->addObject(this, "arena");
+ action->trigger();
+ }
+}
+
+void Sigbattle::Arena::cleanUp()
+{
+ emit(aboutToClearActions());
+ m_isOver = true;
+ QList<Kross::Action*> actions = m_actions->actions();
+ foreach (Kross::Action* action, actions)
+ m_actions->removeAction(action);
+ distributeWinnings();
+ foreach (Player* player, m_players)
+ player->exitArena();
+}
+
+void Sigbattle::Arena::handleAction(TeamMember* teamMember, TeamMember::Action action)
+{
+ TeamMember::ActionData data = action.second;
+ switch (action.first)
+ {
+ case TeamMember::Attack:
+ {
+ Sigscript::MoveWrapper* move = sigmod()->move(data.first.toInt());
+ if (move)
+ {
+ const Sigcore::Script script = move->battleScript();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* kaction = new Kross::Action(m_actions, QUuid::createUuid().toString());
+ kaction->setInterpreter(script.interpreter());
+ kaction->setCode(script.script().toUtf8());
+ kaction->addObject(this, "arena");
+ kaction->addObject(teamMember, "user");
+ for (int i = 0; i < data.second.size(); ++i)
+ kaction->addObject(findMember(data.second[i]), QString("target%1").arg(i));
+ kaction->trigger();
+ }
+ }
+ break;
+ }
+ case TeamMember::Item:
+ {
+ Sigscript::ItemWrapper* item = sigmod()->item(data.first.toInt());
+ if (item)
+ {
+ const Sigcore::Script script = item->script();
+ if (!script.script().isEmpty())
+ {
+ Kross::Action* kaction = new Kross::Action(m_actions, QUuid::createUuid().toString());
+ kaction->setInterpreter(script.interpreter());
+ kaction->setCode(script.script().toUtf8());
+ kaction->addObject(this, "arena");
+ kaction->addObject(findMember(data.second[0]), "target");
+ kaction->trigger();
+ }
+ }
+ break;
+ }
+ case TeamMember::Switch:
+ {
+ Player* player = qobject_cast<Player*>(teamMember->containment());
+ if (player)
+ player->switchOut(teamMember, player->findMember(data.second[0]));
+ break;
+ }
+ case TeamMember::Run:
+ {
+ if (!m_isWild)
+ break;
+ Player* self = qobject_cast<Player*>(teamMember->containment());
+ const int numFlee = self->active().size();
+ bool canRun = true;
+ foreach (Player* player, m_players)
+ {
+ if (self == player)
+ continue;
+ foreach (TeamMember* active, player->active())
+ {
+ for (int i = 0; (i < numFlee) && canRun; ++i)
+ {
+ if (!active->species()->fleeChance().poll())
+ {
+ canRun = false;
+ break;
+ }
+ }
+ }
+ if (!canRun)
+ break;
+ }
+ if (canRun)
+ self->exitArena();
+ break;
+ }
+ case TeamMember::Skip:
+ case TeamMember::Timeout:
+ case TeamMember::Invalid:
+ break;
+ }
+ checkForLosers();
+}
+
+void Sigbattle::Arena::setupBattle()
+{
+ foreach (Player* player, m_players)
+ player->enterArena(this);
+}
+
+void Sigbattle::Arena::distributeWinnings()
+{
+ foreach (Player* player, m_players)
+ {
+ if (!m_spoils.contains(player))
+ continue;
+ Spoil spoil = m_spoils[player];
+ const int net = spoil.first - spoil.second;
+ if (net < 0)
+ player->takeMoney(-net);
+ else if (0 < net)
+ player->giveMoney(net);
+ }
+}
+
+void Sigbattle::Arena::checkForLosers()
+{
+ static QSet<Player*> losers;
+ foreach (Player* player, m_players)
+ {
+
+ }
+}
+
+Sigbattle::TeamMember* Sigbattle::Arena::findMember(const QUuid& id)
+{
+ foreach (Player* player, m_players)
+ {
+ TeamMember* member = player->findMember(id);
+ if (member)
+ return member;
+ }
+ return NULL;
+}