/* * Copyright 2008-2009 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 . */ // Header include #include "TurnArena.h" // Sigencore includes #include #include #include // Sigscript includes #include #include // KDE includes #include #include // Qt includes #include #include #include #include using namespace Sigcore; using namespace Sigscript; using namespace Sigencore; bool sortActions(const TeamMember::RequestedAction& reqAction1, const TeamMember::RequestedAction& reqAction2) { TeamMember::Action action1 = reqAction1.second.isCanceled() ? TeamMember::Action(TeamMember::Timeout, TeamMember::ActionData()) : reqAction1.second; TeamMember::Action action2 = reqAction2.second.isCanceled() ? TeamMember::Action(TeamMember::Timeout, TeamMember::ActionData()) : reqAction2.second; const int priority1 = actionPriority(reqAction1.first, action1); const int priority2 = actionPriority(reqAction1.first, action2); if (priority1 < priority2) return true; else if (priority1 == priority2) { const int speed1 = reqAction1.first->statValue(Sigmod::ST_Speed); const int speed2 = reqAction2.first->statValue(Sigmod::ST_Speed); if (speed1 < speed2) return true; else if (speed1 == speed2) return Sigcore::Fraction::poll(1, 2); } return false; } TurnArena::TurnArena(GameWrapper* sigmod, Config* parent) : Arena(sigmod, parent), m_priorityScripts(new Kross::ActionCollection("priority-scripts", m_actions)) { setupBattle(); } QString TurnArena::name() { return "Sigen turn arena"; } QString TurnArena::description() { return "An arena where creatures act in order of their speed (unless move priority takes precedence)"; } QIcon TurnArena::icon() { // TODO return KIcon(); } QStringList TurnArena::extensions() { return QStringList(); } bool TurnArena::isTeamAllowed(Sigencore::Team* team) { Q_UNUSED(team) // TODO: Use rules format here? return true; } void TurnArena::handleAction(TeamMember* teamMember, TeamMember::Action action) { Arena::handleAction(teamMember, action); } void TurnArena::setupBattle() { connect(this, SIGNAL(battleStarted()), SLOT(processRound())); Arena::setupBattle(); } void TurnArena::distributeWinnings() { Arena::distributeWinnings(); } void TurnArena::checkForLosers() { Arena::checkForLosers(); } void TurnArena::registerScript(const Script& script) { Arena::registerScript(script); } void TurnArena::cleanUp() { Arena::cleanUp(); } void TurnArena::processRound() { emit(roundAboutToStart()); emit(roundStarted()); QFuture reqActions = QtConcurrent::mapped(active(Fighters), &requestDecision); reqActions.waitForFinished(); QList actions = reqActions.results(); qStableSort(actions.begin(), actions.end(), sortActions); foreach (const TeamMember::RequestedAction& reqAction, actions) { TeamMember::Action action = reqAction.second; if (action.first == TeamMember::Attack) { MoveWrapper* move = m_game->move(action.second.first.toInt()); const Script script = move->priorityScript(); ObjectMap objects; objects["arena"] = this; objects["move"] = move; objects["owner"] = reqAction.first; objects["player"] = reqAction.first->team()->player(); objects["sigmod"] = m_game; // TODO: Add other players runScript(QString("priority-%1").arg(QUuid::createUuid().toString()), script, objects, m_priorityScripts)->trigger(); } } qStableSort(actions.begin(), actions.end(), sortActions); foreach (const TeamMember::RequestedAction& action, actions) { if (action.first->currentHp()) handleAction(action.first, action.second); } emit(roundAboutToEnd()); emit(roundEnded()); // TODO: Check if there is anyone left to fight processRound(); }