diff options
| author | Ben Boeckel <MathStuf@gmail.com> | 2009-01-27 22:07:08 -0500 |
|---|---|---|
| committer | Ben Boeckel <MathStuf@gmail.com> | 2009-01-27 22:07:08 -0500 |
| commit | e04c4922a13ed10e9d6b086eacc299f0c5a05984 (patch) | |
| tree | 907e109278adbea9ae100feb61e020174033a3e5 /sigencore/Arena.cpp | |
| parent | d111ea6a931a7120631f6e88e9414cbdb851e0e8 (diff) | |
| download | sigen-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.cpp | 248 |
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; +} |
