/* * Copyright 2008 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" // Sigmod includes #include "../sigmod/Fraction.h" // Sigscript includes #include "../sigscript/MoveWrapper.h" #include "../sigscript/SigmodWrapper.h" // KDE includes #include #include // Qt includes #include #include #include #include bool Sigbattle::sortActions(const TeamMember::RequestedAction& reqAction1, const TeamMember::RequestedAction& reqAction2) { TeamMember::Action action1 = reqAction1.second.isFinished() ? reqAction1.second : TeamMember::Action(TeamMember::Timeout, TeamMember::ActionData()); TeamMember::Action action2 = reqAction2.second.isFinished() ? reqAction2.second : TeamMember::Action(TeamMember::Timeout, TeamMember::ActionData()); 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 Sigmod::Fraction::poll(1, 2); } return false; } Sigbattle::TurnArena::TurnArena(Sigscript::SigmodWrapper* sigmod, QList players, const bool isWild, QObject* parent) : Arena(sigmod, players, isWild, parent), m_watcher(new QFutureWatcher(this)), m_timer(new QTimer(this)) { setupBattle(); m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), m_watcher, SLOT(cancel())); } void Sigbattle::TurnArena::processRound() { emit(roundAboutToStart()); emit(roundStart()); QFuture reqActions = QtConcurrent::mapped(active(), &Sigbattle::requestDecision); m_watcher->setFuture(reqActions); m_timer->start(120000); reqActions.waitForFinished(); m_timer->stop(); QList actions = reqActions.results(); qStableSort(actions.begin(), actions.end(), sortActions); for (int i = 1; i < actions.size(); ++i) { TeamMember::Action action = actions[i].second; if (action.first == TeamMember::Attack) { Sigscript::MoveWrapper* move = sigmod()->move(action.second.first.toInt()); const Sigmod::Script script = move->priorityScript(); 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(actions[i].first, "user"); for (int j = 0; j < i; ++j) kaction->addObject(actions[j].first, QString("fighter%1").arg(j)); kaction->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(roundEnd()); if (!isOver()) processRound(); } void Sigbattle::TurnArena::setupBattle() { // TODO: setup everything for the arena to do with the turns Arena::setupBattle(); }