diff options
author | Ben Boeckel <MathStuf@gmail.com> | 2008-09-05 20:41:05 +0000 |
---|---|---|
committer | Ben Boeckel <MathStuf@gmail.com> | 2008-09-05 20:41:05 +0000 |
commit | b81f5bffa2772eb9bd3c67fb35485ab1ee2d96e7 (patch) | |
tree | 6609f31b1635d948cf7a216c7fea72cfb3c905a0 /sigbattle | |
parent | b99ffef4aa68dd5f0af64de9aec0f610e267d8cc (diff) | |
download | sigen-b81f5bffa2772eb9bd3c67fb35485ab1ee2d96e7.tar.gz sigen-b81f5bffa2772eb9bd3c67fb35485ab1ee2d96e7.tar.xz sigen-b81f5bffa2772eb9bd3c67fb35485ab1ee2d96e7.zip |
[FIX] Moving stuff for the move to the new name, Sigma Game Engine (sigen for short)
git-svn-id: https://pokegen.svn.sourceforge.net/svnroot/pokegen/trunk@249 6ecfd1a5-f3ed-3746-8530-beee90d26b22
Diffstat (limited to 'sigbattle')
-rw-r--r-- | sigbattle/ATBArena.cpp | 62 | ||||
-rw-r--r-- | sigbattle/ATBArena.h | 50 | ||||
-rw-r--r-- | sigbattle/ATBTimer.cpp | 72 | ||||
-rw-r--r-- | sigbattle/ATBTimer.h | 61 | ||||
-rw-r--r-- | sigbattle/ActionQueue.h | 83 | ||||
-rw-r--r-- | sigbattle/Arena.cpp | 117 | ||||
-rw-r--r-- | sigbattle/Arena.h | 84 | ||||
-rw-r--r-- | sigbattle/Bot.h | 55 | ||||
-rw-r--r-- | sigbattle/CMakeLists.txt | 70 | ||||
-rw-r--r-- | sigbattle/Containment.cpp | 34 | ||||
-rw-r--r-- | sigbattle/Containment.h | 59 | ||||
-rw-r--r-- | sigbattle/Ghost.cpp | 94 | ||||
-rw-r--r-- | sigbattle/Ghost.h | 65 | ||||
-rw-r--r-- | sigbattle/GhostBot.h | 32 | ||||
-rw-r--r-- | sigbattle/Global.h | 38 | ||||
-rw-r--r-- | sigbattle/Player.cpp | 41 | ||||
-rw-r--r-- | sigbattle/Player.h | 63 | ||||
-rw-r--r-- | sigbattle/TODO | 1 | ||||
-rw-r--r-- | sigbattle/Team.cpp | 73 | ||||
-rw-r--r-- | sigbattle/Team.h | 47 | ||||
-rw-r--r-- | sigbattle/TeamMember.cpp | 637 | ||||
-rw-r--r-- | sigbattle/TeamMember.h | 207 | ||||
-rw-r--r-- | sigbattle/TurnArena.cpp | 101 | ||||
-rw-r--r-- | sigbattle/TurnArena.h | 59 |
24 files changed, 2205 insertions, 0 deletions
diff --git a/sigbattle/ATBArena.cpp b/sigbattle/ATBArena.cpp new file mode 100644 index 00000000..92a1b71e --- /dev/null +++ b/sigbattle/ATBArena.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 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 includes +#include "ATBArena.h" + +// Pokebattle includes +#include "ATBTimer.h" + +// Qt includes +#include <QtCore/QTimer> + +Pokebattle::ATBArena::ATBArena(QList<Player*> players, QObject* parent) : + Arena(players, parent) +{ + setupBattle(); +} + +void Pokebattle::ATBArena::handleAction(TeamMember* teamMember, TeamMember::Action action) +{ + if (action.first == TeamMember::Skip) + { + m_decisions.enqueue(requestDecision(teamMember)); + return; + } + Arena::handleAction(teamMember, action); +} + +void Pokebattle::ATBArena::processActions() +{ + if (!m_decisions.isEmpty()) + { + while (m_decisions.head().second.isFinished()) + { + TeamMember::RequestedAction action = m_decisions.dequeue(); + handleAction(action.first, action.second.result()); + } + } +} + +void Pokebattle::ATBArena::setupBattle() +{ + m_atbTimer = new ATBTimer(this, m_decisions); + QTimer* moveTimer = new QTimer(this); + connect(moveTimer, SIGNAL(timeout()), this, SLOT(processActions())); + moveTimer->start(100); + Arena::setupBattle(); +} diff --git a/sigbattle/ATBArena.h b/sigbattle/ATBArena.h new file mode 100644 index 00000000..7cb095ec --- /dev/null +++ b/sigbattle/ATBArena.h @@ -0,0 +1,50 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_ATBARENA__ +#define __POKEBATTLE_ATBARENA__ + +// Pokebattle includes +#include "ActionQueue.h" +#include "Arena.h" + +namespace Pokebattle +{ +// Forward declaraions +class ATBTimer; + +class POKEBATTLE_EXPORT ATBArena : public Arena +{ + Q_OBJECT + + public: + ATBArena(QList<Player*> players, QObject* parent); + + void handleAction(TeamMember* teamMember, TeamMember::Action action); + signals: + public slots: + protected slots: + void processActions(); + protected: + void setupBattle(); + private: + ActionQueue m_decisions; + ATBTimer* m_atbTimer; +}; +} + +#endif diff --git a/sigbattle/ATBTimer.cpp b/sigbattle/ATBTimer.cpp new file mode 100644 index 00000000..d2f42ce2 --- /dev/null +++ b/sigbattle/ATBTimer.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 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 "ATBTimer.h" + +// Pokebattle includes +#include "ATBArena.h" + +// Qt includes +#include <QtCore/QtConcurrentFilter> +#include <QtCore/QtConcurrentMap> +#include <QtCore/QFuture> +#include <QtCore/QMultiMap> +#include <QtCore/QTimer> + +// STL includes +#include <functional> + +Pokebattle::ATBTimer::ATBTimer(ATBArena* arena, ActionQueue& actions) : + QThread(arena), + m_arena(arena), + m_actions(actions), + m_timer(new QTimer(this)) +{ + connect(m_timer, SIGNAL(timeout()), this, SLOT(update())); +} + +void Pokebattle::ATBTimer::update() +{ + const QList<TeamMember*> active = m_timeStates.keys(); + QtConcurrent::blockingMap(active, std::bind1st(std::mem_fun(&Pokebattle::ATBTimer::increaseMeter), this)); + // TODO: adjust max time if needed + QList<TeamMember*> overflow = QtConcurrent::blockingFiltered(active, std::bind1st(std::mem_fun(&Pokebattle::ATBTimer::isOverflowed), this)); + QMultiMap<double, TeamMember*> sorter; + foreach (TeamMember* teamMember, overflow) + sorter.insert(m_timeStates[teamMember], teamMember); + overflow = sorter.values(); + foreach(TeamMember* teamMember, overflow) + m_actions.enqueue(requestDecision(teamMember)); +} + +void Pokebattle::ATBTimer::run() +{ + m_timer->start(50); + exec(); +} + +void Pokebattle::ATBTimer::increaseMeter(const TeamMember* teamMember) +{ + // TODO: tweak this(?) + m_timeStates[const_cast<TeamMember*>(teamMember)] += teamMember->statValue(Pokemod::ST_Speed) / 10; +} + +bool Pokebattle::ATBTimer::isOverflowed(const TeamMember* teamMember) const +{ + return m_threshold < m_timeStates[const_cast<TeamMember*>(teamMember)]; +} diff --git a/sigbattle/ATBTimer.h b/sigbattle/ATBTimer.h new file mode 100644 index 00000000..ff84ce54 --- /dev/null +++ b/sigbattle/ATBTimer.h @@ -0,0 +1,61 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_ATBTIMER__ +#define __POKEBATTLE_ATBTIMER__ + +// Pokebattle includes +#include "Global.h" + +// Qt includes +#include <QtCore/QMap> +#include <QtCore/QThread> + +// Forward declarations +class QTimer; + +namespace Pokebattle +{ +class ActionQueue; +class ATBArena; +class Player; +class TeamMember; + +class POKEBATTLE_EXPORT ATBTimer : public QThread +{ + Q_OBJECT + + public: + ATBTimer(ATBArena* arena, ActionQueue& actions); + protected slots: + void update(); + protected: + void run(); + private: + void increaseMeter(const TeamMember* teamMember); + bool isOverflowed(const TeamMember* teamMember) const; + + ATBArena* m_arena; + ActionQueue& m_actions; + QMap<TeamMember*, double> m_timeStates; + double m_threshold; + QTimer* m_timer; +}; + +} + +#endif diff --git a/sigbattle/ActionQueue.h b/sigbattle/ActionQueue.h new file mode 100644 index 00000000..3641755b --- /dev/null +++ b/sigbattle/ActionQueue.h @@ -0,0 +1,83 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_ACTIONQUEUE__ +#define __POKEBATTLE_ACTIONQUEUE__ + +// Pokebattle includes +#include "Global.h" +#include "TeamMember.h" + +// Qt includes +#include <QtCore/QMutex> +#include <QtCore/QMutexLocker> +#include <QtCore/QQueue> + +namespace Pokebattle +{ +class POKEBATTLE_EXPORT ActionQueue : public QQueue<TeamMember::RequestedAction> +{ + public: + ActionQueue(); + + TeamMember::RequestedAction dequeue(); + void enqueue(const TeamMember::RequestedAction& action); + + TeamMember::RequestedAction& head(); + + void lock(); + void unlock(); + private: + QMutex m_mutex; +}; + +inline ActionQueue::ActionQueue() : + QQueue<TeamMember::RequestedAction>() +{ +} + +inline TeamMember::RequestedAction ActionQueue::dequeue() +{ + QMutexLocker locker(&m_mutex); + return QQueue<TeamMember::RequestedAction>::dequeue(); +} + +inline void ActionQueue::enqueue(const TeamMember::RequestedAction& action) +{ + QMutexLocker locker(&m_mutex); + QQueue<TeamMember::RequestedAction>::enqueue(action); +} + +inline TeamMember::RequestedAction& ActionQueue::head() +{ + QMutexLocker locker(&m_mutex); + return QQueue<TeamMember::RequestedAction>::head(); +} + +inline void ActionQueue::lock() +{ + m_mutex.lock(); +} + +inline void ActionQueue::unlock() +{ + m_mutex.unlock(); +} + +} + +#endif diff --git a/sigbattle/Arena.cpp b/sigbattle/Arena.cpp new file mode 100644 index 00000000..84c98dd9 --- /dev/null +++ b/sigbattle/Arena.cpp @@ -0,0 +1,117 @@ +/* + * 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" + +// Pokebattle includes +#include "Player.h" + +// Pokemod includes +#include "../pokemod/Script.h" + +// Qt includes +#include <QtCore/QtConcurrentRun> + +// KDE includes +#include <kross/core/action.h> +#include <kross/core/actioncollection.h> +#include <kross/core/manager.h> + +Pokebattle::TeamMember::RequestedAction Pokebattle::requestDecision(TeamMember* teamMember) +{ + return TeamMember::RequestedAction(teamMember, QtConcurrent::run(decision, teamMember)); +} + +Pokebattle::TeamMember::Action Pokebattle::decision(TeamMember* teamMember) +{ + return teamMember->requestAction(); +} + +Pokebattle::Arena::Arena(QList<Player*> players, QObject* parent) : + Pokescripting::Config(parent), + 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); +} + +Pokebattle::Arena::~Arena() +{ + delete m_actions; +} + +QList<Pokebattle::TeamMember*> Pokebattle::Arena::active() const +{ + QList<Pokebattle::TeamMember*> active; + foreach (Player* player, m_players) + active += player->active(); + return active; +} + +int Pokebattle::Arena::numActiveTeams() const +{ + int active = 0; + foreach (Player* player, m_players) + active += !player->active().isEmpty(); + return active; +} + +void Pokebattle::Arena::registerScript(const QString& name, const Pokemod::Script& script) +{ + Kross::Action* action = new Kross::Action(m_actions, name); + action->setInterpreter(script.interpreter()); + action->setCode(script.script().toUtf8()); + action->addObject(this, "arena"); + action->trigger(); +} + +void Pokebattle::Arena::cleanUp() +{ + // TODO: clean up everything +} + +void Pokebattle::Arena::handleAction(TeamMember* teamMember, TeamMember::Action action) +{ + switch (action.first) + { + case TeamMember::Attack: + // TODO: Start move script + break; + case TeamMember::Item: + // TODO: Start item script + break; + case TeamMember::Switch: + // TODO: Switch with the other member + break; + case TeamMember::Run: + // TODO: Run if possible, skip if fail + break; + case TeamMember::Skip: + case TeamMember::Timeout: + case TeamMember::Invalid: + break; + } +} + +void Pokebattle::Arena::setupBattle() +{ + // TODO: setup all the battle stuff +} diff --git a/sigbattle/Arena.h b/sigbattle/Arena.h new file mode 100644 index 00000000..9a3a69e9 --- /dev/null +++ b/sigbattle/Arena.h @@ -0,0 +1,84 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_ARENA__ +#define __POKEBATTLE_ARENA__ + +// Pokebattle includes +#include "Global.h" +#include "Team.h" +#include "TeamMember.h" + +// Qt includes +#include <QtCore/QList> +#include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QSet> +#include <QtCore/QUuid> + +// Forward declarations +namespace Kross +{ +class Action; +class ActionCollection; +} +namespace Pokemod +{ +class Script; +} + +namespace Pokebattle +{ +class Player; + +class POKEBATTLE_EXPORT Arena : public Pokescripting::Config +{ + Q_OBJECT + + public: + Arena(QList<Player*> players, QObject* parent); + ~Arena(); + + QList<TeamMember*> active() const; + int numActiveTeams() const; + + Kross::Action* script(const QString& name); + signals: + void battleStart(); + void battleEnd(); + public slots: + void registerScript(const QString& name, const Pokemod::Script& script); + protected slots: + void cleanUp(); + protected: + virtual void handleAction(TeamMember* teamMember, TeamMember::Action action); + + virtual void setupBattle(); + + QList<Player*> m_players; + Kross::ActionCollection* m_actions; + private: + const QUuid m_id; +}; + +TeamMember::RequestedAction requestDecision(TeamMember* teamMember); +TeamMember::Action decision(TeamMember* teamMember); + +} +Q_DECLARE_METATYPE(Pokebattle::Arena*) + +#endif diff --git a/sigbattle/Bot.h b/sigbattle/Bot.h new file mode 100644 index 00000000..fef5d449 --- /dev/null +++ b/sigbattle/Bot.h @@ -0,0 +1,55 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_BOT__ +#define __POKEBATTLE_BOT__ + +// Pokebattle includes +#include "Player.h" + +// Standard library includes +#include <climits> + +// Forward declarations +namespace Pokemod +{ +class MapTrainer; +} + +namespace Pokebattle +{ +class Arena; +class GhostBot; + +class POKEBATTLE_EXPORT Bot : public Player +{ + Q_OBJECT + + public: + Bot(const Pokemod::MapTrainer& trainer); + signals: + public slots: + protected slots: + protected: + private: + long alphaBeta(const Arena& arena, const int trainerClass, const long alpha = LONG_MIN, const long beta = LONG_MAX); + + QList<GhostBot*> m_enemies; +}; +} + +#endif diff --git a/sigbattle/CMakeLists.txt b/sigbattle/CMakeLists.txt new file mode 100644 index 00000000..ec6ebcc8 --- /dev/null +++ b/sigbattle/CMakeLists.txt @@ -0,0 +1,70 @@ +PROJECT(pokebattle) + +IF(NOT BUILT_FROM_ROOT) + MESSAGE(FATAL_ERROR "Not built from source root") +ENDIF(NOT BUILT_FROM_ROOT) + +ADD_DEFINITIONS(-DMAKE_POKEBATTLE_LIB) + +SET(pokebattle_MOC_HEADERS + Arena.h + ATBArena.h + ATBTimer.h + Bot.h + Containment.h + GhostBot.h + Ghost.h + Player.h + Team.h + TeamMember.h + TurnArena.h +) +QT4_WRAP_CPP(pokebattle_MOC_SRCS ${pokebattle_MOC_HEADERS}) +SET(pokebattle_HEADERS + ${pokebattle_MOC_HEADERS} + ActionQueue.h +) +SET(pokebattle_DEVEL + ${pokebattle_HEADERS} +) +SET(pokebattle_SRCS + Arena.cpp + ATBArena.cpp + ATBTimer.cpp + Containment.cpp + Ghost.cpp + Player.cpp + Team.cpp + TeamMember.cpp + TurnArena.cpp +) + +ADD_LIBRARY(pokebattle + ${pokebattle_SRCS} + ${pokebattle_MOC_SRCS} +) +SET_TARGET_PROPERTIES(pokebattle + PROPERTIES + VERSION ${POKEGEN_VERSION} + SOVERSION ${POKEGEN_SOVERSION} + LINK_INTERFACE_LIBRARIES "" +) +TARGET_LINK_LIBRARIES(pokebattle + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ${KDE4_KROSSCORE_LIBRARY} + pokemod + pokescripting +) + +INSTALL( + TARGETS pokebattle + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX} + COMPONENT runtime +) + +INSTALL( + FILES ${pokebattle_DEVEL} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME} + COMPONENT development +) diff --git a/sigbattle/Containment.cpp b/sigbattle/Containment.cpp new file mode 100644 index 00000000..7dd31002 --- /dev/null +++ b/sigbattle/Containment.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 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 "Containment.h" + +Pokebattle::Containment::Containment(QObject* parent) : + QObject(parent) +{ +} + +QList<Pokebattle::TeamMember*> Pokebattle::Containment::members() const +{ + return m_members; +} + +Pokescripting::PokemodWrapper* Pokebattle::Containment::pokemod() const +{ + // TODO: return PokemodWrapper +} diff --git a/sigbattle/Containment.h b/sigbattle/Containment.h new file mode 100644 index 00000000..e19061e9 --- /dev/null +++ b/sigbattle/Containment.h @@ -0,0 +1,59 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_CONTAINMENT__ +#define __POKEBATTLE_CONTAINMENT__ + +// Pokebattle includes +#include "Global.h" + +// Qt includes +#include <QtCore/QMetaType> +#include <QtCore/QObject> + +// Forward declarations +namespace Pokescripting +{ +class PokemodWrapper; +} + +namespace Pokebattle +{ +class TeamMember; + +class POKEBATTLE_EXPORT Containment : public QObject +{ + Q_OBJECT + + public: + Containment(QObject* parent); + + QList<TeamMember*> members() const; + + virtual bool isMutable() const = 0; + + Pokescripting::PokemodWrapper* pokemod() const; + signals: + public slots: + protected slots: + protected: + QList<TeamMember*> m_members; +}; +} +Q_DECLARE_METATYPE(Pokebattle::Containment*) + +#endif diff --git a/sigbattle/Ghost.cpp b/sigbattle/Ghost.cpp new file mode 100644 index 00000000..4750636a --- /dev/null +++ b/sigbattle/Ghost.cpp @@ -0,0 +1,94 @@ +/* + * 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 "Ghost.h" + +// Ghost(const PokeMod::Pokemod& par, const unsigned s, const unsigned l, const unsigned t) : +// Pokemon(par, s, l), +// teamSize(t), +// unknownMoves(par->GetMaxMoves()) +// { +// for (unsigned i = 0; i < PokeMod::ST_End_GSC; ++i) +// { +// dv[i] = 0; +// statExp[i] = 0; +// minStats[i] = GetStat(i); +// dv[i] = pokemod->GetMaxDV(); +// statExp[i] = 65535; +// maxStats[i] = GetStat(i); +// } +// Species* pkmn = pokemod->GetSpeciesByID(s); +// if (pkmn->GetNumAbilities() == 1) +// FeedAbility(pkmn->GetAbility(0)); +// } +// +// void FeedAttack(const unsigned actualDamage, const unsigned stat, const unsigned otherLevel, const unsigned power, const bool isAttacker) +// { +// +// } +// +// void FeedItem(const unsigned i) +// { +// items.append(i); +// } +// +// void FeedMove(const unsigned m) +// { +// if (!moves.contains(m)) +// { +// moves.insert(m); +// --unknownMoves; +// moveChances[m] = UINT_MAX; +// for (QMutableMapIterator<unsigned, unsigned> i(moveChances); i.hasNext(); i.next()) +// { +// if (i.value() != UINT_MAX) +// { +// i.value() *= unknownMoves; +// i.value() /= (unknownMoves + 1); +// if (!i.value()) +// moveChances.erase(i); +// } +// } +// for (QListIterator<MoveCombo> i(moveCombos); i.hasNext(); i.next()) +// { +// if (i.prereqs.intersect(moves).size() && !moves.contains(i.move)) +// moves[i.move] *= i.chance; +// } +// } +// } +// +// void FeedMoveChance(const unsigned m, const unsigned weight) +// { +// moveChances[m] = weight; +// } +// +// void FeedAbility(const unsigned a) +// { +// ability = a; +// } +// +// void UpdateHP() +// { +// curHP = hpPercent * maxStats[PokeMod::ST_HP]; +// } +// +// void SetHP(const Frac p) +// { +// hpPercent = p; +// UpdateHP(); +// } diff --git a/sigbattle/Ghost.h b/sigbattle/Ghost.h new file mode 100644 index 00000000..325f7108 --- /dev/null +++ b/sigbattle/Ghost.h @@ -0,0 +1,65 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_GHOST__ +#define __POKEBATTLE_GHOST__ + +// Pokebattle includes +#include "TeamMember.h" + +namespace Pokebattle +{ +class POKEBATTLE_EXPORT Ghost : public TeamMember +{ + Q_OBJECT + +// public: +// Ghost(const PokeMod::Pokemod& par, const unsigned s, const unsigned l); +// +// void FeedAttack(const unsigned actualDamage, const unsigned stat, const unsigned otherLevel, const unsigned power, const bool isAttacker); +// void FeedItem(const unsigned i); +// void FeedMove(const unsigned m); +// void FeedMoveChance(const unsigned m, const unsigned weight); +// void FeedMoveCombo(const MoveCombo m); +// void FeedAbility(const unsigned a); +// +// void UpdateHP(); +// void SetHP(const Frac p); +// private: +// struct MoveCombo +// { +// public: +// MoveCombo(const QSet<unsigned> p, const unsigned m, const unsigned c) : +// prereqs(p), +// move(m), +// chance(c) +// { +// } +// QSet<unsigned> prereqs; +// unsigned move; +// const unsigned chance; +// }; +// +// unsigned minStats[PokeMod::ST_End_GSC]; +// unsigned maxStats[PokeMod::ST_End_GSC]; +// QMap<unsigned, unsigned> moveChances; +// QList<MoveCombo> moveCombos; +// unsigned unknownMoves; +}; +} + +#endif diff --git a/sigbattle/GhostBot.h b/sigbattle/GhostBot.h new file mode 100644 index 00000000..459f2ccf --- /dev/null +++ b/sigbattle/GhostBot.h @@ -0,0 +1,32 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_GHOSTBOT__ +#define __POKEBATTLE_GHOSTBOT__ + +// Pokebattle includes +#include "Player.h" + +namespace Pokebattle +{ +class POKEBATTLE_EXPORT GhostBot : public Player +{ + Q_OBJECT +}; +} + +#endif diff --git a/sigbattle/Global.h b/sigbattle/Global.h new file mode 100644 index 00000000..713d8c9d --- /dev/null +++ b/sigbattle/Global.h @@ -0,0 +1,38 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_GLOBAL__ +#define __POKEBATTLE_GLOBAL__ + +// KDE includes +#include <kdemacros.h> + +#ifndef POKEBATTLE_EXPORT +# ifdef MAKE_POKEBATTLE_LIB + /* We are building this library */ +# define POKEBATTLE_EXPORT KDE_EXPORT +# else + /* We are using this library */ +# define POKEBATTLE_EXPORT KDE_IMPORT +# endif +#endif + +# ifndef POKEBATTLE_EXPORT_DEPRECATED +# define POKEBATTLE_EXPORT_DEPRECATED KDE_DEPRECATED POKEBATTLE_EXPORT +# endif + +#endif diff --git a/sigbattle/Player.cpp b/sigbattle/Player.cpp new file mode 100644 index 00000000..13e6076a --- /dev/null +++ b/sigbattle/Player.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 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 "Player.h" + +Pokebattle::Player::Player(QObject* parent) : + Team(parent), + m_arena(NULL) +{ +} + +void Pokebattle::Player::enterArena(Arena* arena) +{ + // TODO: Get a list of the active members + // TODO: Let them know that they are active +} + +QList<Pokebattle::TeamMember*> Pokebattle::Player::active() +{ + // TODO: return active members +} + +void Pokebattle::Player::exitArena() +{ + // TODO: Tell all active members that they can leave now +} diff --git a/sigbattle/Player.h b/sigbattle/Player.h new file mode 100644 index 00000000..04b3d872 --- /dev/null +++ b/sigbattle/Player.h @@ -0,0 +1,63 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_PLAYER__ +#define __POKEBATTLE_PLAYER__ + +// Pokebattle includes +#include "Global.h" +#include "Team.h" +#include "TeamMember.h" + +// Qt includes +#include <QtCore/QObject> + +// Forward declarations +namespace Pokemod +{ +class Pokemod; +} + +namespace Pokebattle +{ +class Team; + +class POKEBATTLE_EXPORT Player : public Team +{ + Q_OBJECT + + public: + Player(QObject* parent); + + void enterArena(Arena* arena); + + QList<TeamMember*> active(); + + const Pokemod::Pokemod* pokemod() const; + signals: + public slots: + void exitArena(); + + virtual TeamMember::Action requestAction(const TeamMember* teamMember) const = 0; + protected slots: + protected: + Arena* m_arena; +}; +} +Q_DECLARE_METATYPE(Pokebattle::Player*) + +#endif diff --git a/sigbattle/TODO b/sigbattle/TODO new file mode 100644 index 00000000..b9357c4b --- /dev/null +++ b/sigbattle/TODO @@ -0,0 +1 @@ +Put global scripts into requesting for things diff --git a/sigbattle/Team.cpp b/sigbattle/Team.cpp new file mode 100644 index 00000000..22adea08 --- /dev/null +++ b/sigbattle/Team.cpp @@ -0,0 +1,73 @@ +/* + * 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 "Team.h" + +Pokebattle::Team::Team(QObject* parent) : + Containment(parent) +{ + // TODO: construct +} + +// Team::Team(const PokeMod::Pokemod& par) : +// active(0), +// parent(par) +// { +// } +// +// void Team::AddItem(const unsigned i, const unsigned amt) +// { +// if (amt) +// items[i] = amt; +// } +// +// void Team::UseItem(const unsigned i) +// { +// if (items.contains(i) && (items[i] != UINT_MAX)) +// { +// --items[i]; +// if (!items[i]) +// items.remove(i); +// } +// } +// +// void Team::AddPokemon(Pokemon& p) +// { +// pokemon.append(&p); +// } +// +// void Team::SwapPokemon(const unsigned a, const unsigned b) +// { +// if ((a < pokemon.size()) && (b < pokemon.size())) +// { +// Pokemon* p = pokemon[a]; +// pokemon[a] = pokemon[b]; +// pokemon[b] = p; +// } +// } +// +// bool Team::SetActivePokemon(const unsigned a) +// { +// if ((a < pokemon.size()) && pokemon[a]->CanFight()) +// active = a; +// } + +bool Pokebattle::Team::isMutable() const +{ + return true; +} diff --git a/sigbattle/Team.h b/sigbattle/Team.h new file mode 100644 index 00000000..63a85095 --- /dev/null +++ b/sigbattle/Team.h @@ -0,0 +1,47 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_TEAM__ +#define __POKEBATTLE_TEAM__ + +// Pokebattle includes +#include "Containment.h" + +namespace Pokebattle +{ +// Forward declarations +class Arena; + +class POKEBATTLE_EXPORT Team : public Containment +{ + Q_OBJECT + + public: + Team(QObject* parent); + + virtual bool isMutable() const; + signals: + void teamKnockedOut(); + public slots: + protected slots: + protected: + Arena* m_arena; +}; +} +Q_DECLARE_METATYPE(Pokebattle::Team*) + +#endif diff --git a/sigbattle/TeamMember.cpp b/sigbattle/TeamMember.cpp new file mode 100644 index 00000000..84727cb7 --- /dev/null +++ b/sigbattle/TeamMember.cpp @@ -0,0 +1,637 @@ +/* + * 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" + +// Pokebattle includes +#include "Arena.h" +#include "Containment.h" +#include "Player.h" + +// Pokescripting includes +#include "../pokescripting/AbilityWrapper.h" +#include "../pokescripting/ItemWrapper.h" +#include "../pokescripting/MapTrainerTeamMemberWrapper.h" +#include "../pokescripting/MoveWrapper.h" +#include "../pokescripting/NatureWrapper.h" +#include "../pokescripting/PokemodWrapper.h" +#include "../pokescripting/RulesWrapper.h" +#include "../pokescripting/StatusWrapper.h" +#include "../pokescripting/SpeciesWrapper.h" +#include "../pokescripting/SpeciesAbilityWrapper.h" +#include "../pokescripting/SpeciesItemWrapper.h" +#include "../pokescripting/SpeciesMoveWrapper.h" + +// Pokemod includes +#include "../pokemod/Hat.h" + +// Qt includes +#include <QtCore/QUuid> + +// KDE includes +#include <kross/core/action.h> +#include <kross/core/actioncollection.h> +#include <kross/core/manager.h> + +// C includes +#include <cmath> + +// TODO: Current HP +// TODO: Script cleanup (battle) + +int Pokebattle::actionPriority(const TeamMember* teamMember, const TeamMember::Action& action) +{ + int priority = INT_MAX; + switch (action.first) + { + case TeamMember::Attack: + priority = teamMember->pokemod()->move(action.second.first.toString())->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; +} + +Pokebattle::TeamMember::TeamMember(const int speciesId, const QString& name, const int level, Containment* containment, const bool suppressItems) : + Pokescripting::Config(containment), + m_containment(containment), + m_id(QUuid::createUuid()) +{ + makeConnections(); + setSpecies(pokemod()->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 < Pokemod::ST_End_GSC; ++i) + m_statExp[i] = 0; + if (m_containment->isMutable()) + { + const Pokemod::Script script = m_species->evolution(); + Kross::Action* evolution = new Kross::Action(Kross::Manager::self().actionCollection()->collection("evolutions"), QString("evolution-%1").arg(QUuid::createUuid().toString())); + evolution->setInterpreter(script.interpreter()); + evolution->setCode(script.script().toUtf8()); + evolution->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals); + evolution->trigger(); + } + m_currentHp = statValue(Pokemod::ST_HP); +} + +Pokebattle::TeamMember::TeamMember(Pokescripting::MapTrainerTeamMemberWrapper* teamMember, Containment* containment) : + Pokescripting::Config(containment), + m_containment(containment), + m_id(QUuid::createUuid()) +{ + makeConnections(); + setSpecies(teamMember->species()); + setName(m_species->name()); + setLevel(teamMember->level()); + m_items = teamMember->items(); + 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 < Pokemod::ST_End_GSC; ++i) + m_statExp[i] = 0; + m_currentHp = statValue(Pokemod::ST_HP); +} + +QUuid Pokebattle::TeamMember::id() const +{ + return m_id; +} + +QString Pokebattle::TeamMember::name() const +{ + if (value("name").canConvert<QString>()) + return value("name").toString(); + return m_name; +} + +long long Pokebattle::TeamMember::currentHp() const +{ + return m_currentHp; +} + +Pokescripting::SpeciesWrapper* Pokebattle::TeamMember::species() const +{ + if (value("species").canConvert<Pokescripting::SpeciesWrapper*>()) + return value("species").value<Pokescripting::SpeciesWrapper*>(); + return m_species; +} + +int Pokebattle::TeamMember::level() const +{ + return m_level; +} + +Pokebattle::TeamMember::Gender Pokebattle::TeamMember::gender() const +{ + if (value("gender").canConvert<Gender>()) + return value("gender").value<Gender>(); + return m_gender; +} + +long long Pokebattle::TeamMember::levelExperience() const +{ + if (value("levelExperience").canConvert<long long>()) + return value("levelExperience").toLongLong(); + return m_levelExp; +} + +int Pokebattle::TeamMember::baseStat(const Pokemod::Stat stat) const +{ + if (value("overrideBaseStats").canConvert<bool>() && value("overrideBaseStats").toBool()) + return species()->baseStat(stat); + return m_species->baseStat(stat); +} + +long long Pokebattle::TeamMember::statExperience(const Pokemod::Stat stat) const +{ + const QString valueName = QString("statExperience-%1").arg((pokemod()->rules()->specialSplit() ? Pokemod::StatGSCStr : Pokemod::StatRBYStr)[stat]); + if (value(valueName).canConvert<long long>()) + return value(valueName).toLongLong(); + return m_statExp[stat]; +} + +int Pokebattle::TeamMember::dv(const Pokemod::Stat stat) const +{ + const QString valueName = QString("dv-%1").arg((pokemod()->rules()->specialSplit() ? Pokemod::StatGSCStr : Pokemod::StatRBYStr)[stat]); + if (value(valueName).canConvert<int>()) + { + const int dv = value(valueName).toInt(); + if (dv < (pokemod()->rules()->specialDVSplit() ? 32 : 16)) + return dv; + } + return m_dv[stat]; +} + +long long Pokebattle::TeamMember::statValue(const Pokemod::Stat stat, const long long exp) const +{ + long long statValue; + if (exp < 0) + statValue = statExperience(stat); + else + statValue = exp; + if (!pokemod()->rules()->effortValuesAllowed() && statValue) + statValue = sqrt(statValue - 1) + 1; + statValue >>= 2; + statValue += baseStat(stat) << 1; + if (pokemod()->rules()->specialDVSplit()) + { + if (stat == Pokemod::ST_SpecialDefense) + statValue += dv(Pokemod::ST_Special) << 1; + else + statValue += dv(stat) << 1; + } + else + statValue += dv(stat); + statValue *= double(m_level) / pokemod()->rules()->maxLevel(); + if (stat == Pokemod::ST_HP) + statValue += 10 + m_level; + else + { + statValue += 5; + Pokemod::Fraction multiplier; + foreach (Pokescripting::NatureWrapper* nature, m_natures) + multiplier *= nature->stat(stat); + statValue *= multiplier; + } + return statValue; +} + +long long Pokebattle::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 Pokemod::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 Pokemod::Species::Fading: + return 6 * cube / 5 - 15 * square + 100 * level - 140; + case Pokemod::Species::Slow: + return 5 * cube / 4; + case Pokemod::Species::Normal: + return cube; + case Pokemod::Species::Fast: + return 4 * cube / 5; + case Pokemod::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 Pokebattle::TeamMember::canLearnMove(Pokescripting::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; +} + +void Pokebattle::TeamMember::boostLevels(const int levels) +{ + if ((m_level + levels) < pokemod()->rules()->maxLevel()) + { + for (int i = 0; i < levels; ++i) + setLevel(m_level + 1); + } +} + +void Pokebattle::TeamMember::evolveInto(Pokescripting::SpeciesWrapper* newSpecies) +{ + emit(evolveStart()); + int oldStats[Pokemod::ST_End_GSC] = {}; + int newStats[Pokemod::ST_End_GSC] = {}; + oldStats[Pokemod::ST_Attack] = statValue(Pokemod::ST_Attack); + oldStats[Pokemod::ST_Defense] = statValue(Pokemod::ST_Defense); + oldStats[Pokemod::ST_Speed] = statValue(Pokemod::ST_Speed); + if (pokemod()->rules()->specialSplit()) + { + oldStats[Pokemod::ST_SpecialAttack] = statValue(Pokemod::ST_SpecialAttack); + oldStats[Pokemod::ST_SpecialDefense] = statValue(Pokemod::ST_SpecialDefense); + } + else + oldStats[Pokemod::ST_Special] = statValue(Pokemod::ST_Special); + setSpecies(newSpecies); + newStats[Pokemod::ST_Attack] = statValue(Pokemod::ST_Attack); + newStats[Pokemod::ST_Defense] = statValue(Pokemod::ST_Defense); + newStats[Pokemod::ST_Speed] = statValue(Pokemod::ST_Speed); + if (pokemod()->rules()->specialSplit()) + { + newStats[Pokemod::ST_SpecialAttack] = statValue(Pokemod::ST_SpecialAttack); + newStats[Pokemod::ST_SpecialDefense] = statValue(Pokemod::ST_SpecialDefense); + } + else + newStats[Pokemod::ST_Special] = statValue(Pokemod::ST_Special); + if (oldStats[Pokemod::ST_Attack] != newStats[Pokemod::ST_Attack]) + emit(statChanged(Pokemod::ST_Attack, newStats[Pokemod::ST_Attack])); + if (oldStats[Pokemod::ST_Defense] != newStats[Pokemod::ST_Defense]) + emit(statChanged(Pokemod::ST_Defense, newStats[Pokemod::ST_Defense])); + if (oldStats[Pokemod::ST_Speed] != newStats[Pokemod::ST_Speed]) + emit(statChanged(Pokemod::ST_Speed, newStats[Pokemod::ST_Speed])); + if (pokemod()->rules()->specialSplit()) + { + if (oldStats[Pokemod::ST_SpecialAttack] != newStats[Pokemod::ST_SpecialAttack]) + emit(statChanged(Pokemod::ST_SpecialAttack, newStats[Pokemod::ST_SpecialAttack])); + if (oldStats[Pokemod::ST_SpecialDefense] != newStats[Pokemod::ST_SpecialDefense]) + emit(statChanged(Pokemod::ST_SpecialDefense, newStats[Pokemod::ST_SpecialDefense])); + } + else + { + if (oldStats[Pokemod::ST_Special] != newStats[Pokemod::ST_Special]) + emit(statChanged(Pokemod::ST_Special, newStats[Pokemod::ST_Special])); + } + emit(evolveEnd()); +} + +void Pokebattle::TeamMember::setName(const QString& name) +{ + if (m_name != name) + { + const QString oldName = m_name; + m_name = name; + emit(nameChanged(oldName, m_name)); + } +} + +void Pokebattle::TeamMember::cureStatus(Pokescripting::StatusWrapper* status) +{ + if (m_status.contains(status)) + { + QList<Kross::Action*> actions = m_status.values(status); + foreach (Kross::Action* action, actions) + delete action; + m_status.remove(status); + emit(statusCured(status)); + } +} + +void Pokebattle::TeamMember::giveStatus(Pokescripting::StatusWrapper* status) +{ + Q_ASSERT(pokemod()->statusIndex(status) != INT_MAX); + if (!m_status.contains(status)) + { + const Pokemod::Script script = status->worldScript(); + Kross::Action* statusAction = new Kross::Action(Kross::Manager::self().actionCollection()->collection("status"), QString("status-%1").arg(QUuid::createUuid().toString())); + statusAction->setInterpreter(script.interpreter()); + statusAction->setCode(script.script().toUtf8()); + statusAction->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals); + statusAction->trigger(); + m_status.insert(status, statusAction); + emit(statusInflicted(status)); + } +} + +void Pokebattle::TeamMember::giveLevelExp(const int exp) +{ + if (m_level == pokemod()->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 Pokebattle::TeamMember::giveStatExp(const Pokemod::Stat stat, const int exp) +{ + Q_ASSERT(stat < (pokemod()->rules()->specialSplit() ? Pokemod::ST_End_GSC : Pokemod::ST_End_RBY)); + const int oldStat = statValue(stat); + int expToGive = exp; + if (pokemod()->rules()->effortValuesAllowed()) + { + int totalEV = 0; + for (int i = 0; i < Pokemod::ST_End_GSC; ++i) + totalEV += m_statExp[i]; + while (expToGive && (totalEV < pokemod()->rules()->maxTotalEV()) && (m_statExp[stat] < pokemod()->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 Pokebattle::TeamMember::takeItem(Pokescripting::ItemWrapper* item) +{ + if (m_items.contains(item)) + { + m_items.removeAt(m_items.indexOf(item)); + emit(itemTaken(item)); + } +} + +void Pokebattle::TeamMember::giveItem(Pokescripting::ItemWrapper* item) +{ + if (m_items.size() < pokemod()->rules()->maxHeldItems()) + { + m_items.append(item); + emit(itemGiven(item)); + } +} + +void Pokebattle::TeamMember::forgetMove(Pokescripting::MoveWrapper* move) +{ + if (m_moves.contains(move)) + { + m_moves.removeAll(move); + emit(moveForgotten(move)); + } +} + +void Pokebattle::TeamMember::teachMove(Pokescripting::MoveWrapper* move) +{ + if (canLearnMove(move)) + { + if (m_moves.size() < pokemod()->rules()->maxMoves()) + { + m_moves.append(move); + emit(moveLearned(move)); + } + emit(movesFull(move)); + } + emit(unlearnableMove(move)); +} + +Pokebattle::TeamMember::Action Pokebattle::TeamMember::requestAction() const +{ + Player* player = qobject_cast<Player*>(m_containment); + if (player) + return player->requestAction(this); + return Action(Invalid, ActionData()); +} + +void Pokebattle::TeamMember::makeActive(Arena* arena) +{ + QList<Pokescripting::StatusWrapper*> statuses = m_status.uniqueKeys(); + foreach (Pokescripting::StatusWrapper* status, statuses) + { + const Pokemod::Script script = status->battleScript(); + Kross::Action* statusScript = new Kross::Action(Kross::Manager::self().actionCollection()->collection("status"), QString("status-%1").arg(QUuid::createUuid().toString())); + statusScript->setInterpreter(script.interpreter()); + statusScript->setCode(script.script().toUtf8()); + statusScript->addObject(arena, "arena", Kross::ChildrenInterface::AutoConnectSignals); + statusScript->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals); + statusScript->trigger(); + m_statusBattleScripts.append(statusScript); + } + QList<Pokescripting::AbilityWrapper*> abilities = m_abilities.keys(); + foreach (Pokescripting::AbilityWrapper* ability, abilities) + { + const Pokemod::Script script = ability->battleScript(); + Kross::Action* abilityScript = new Kross::Action(Kross::Manager::self().actionCollection()->collection("ability"), QString("ability-%1").arg(QUuid::createUuid().toString())); + abilityScript->setInterpreter(script.interpreter()); + abilityScript->setCode(script.script().toUtf8()); + abilityScript->addObject(arena, "arena", Kross::ChildrenInterface::AutoConnectSignals); + abilityScript->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals); + abilityScript->trigger(); + m_abilityBattleScripts.append(abilityScript); + } +} + +void Pokebattle::TeamMember::writeBack() +{ + // TODO: write back all (applicable) differences between config and local storage +} + +Pokescripting::PokemodWrapper* Pokebattle::TeamMember::pokemod() const +{ + return m_containment->pokemod(); +} + +void Pokebattle::TeamMember::setSpecies(Pokescripting::SpeciesWrapper* species) +{ + m_species = species; + emit(speciesChanged(m_species)); +} + +void Pokebattle::TeamMember::setLevel(const int level) +{ + emit(levelAboutToGrow()); + m_level = level; + emit(levelGrown(level)); + m_levelExp = calcExp(); +} + +void Pokebattle::TeamMember::levelGrown() +{ + for (int i = 0; i < m_species->moveCount(); ++i) + { + Pokescripting::SpeciesMoveWrapper* move = m_species->move(i); + if (move->level() == m_level) + teachMove(move->move()); + } +} + +void Pokebattle::TeamMember::makeConnections() +{ + // TODO: make connections that are necessary (watching Config changes mainly) +} + +void Pokebattle::TeamMember::initAbility(Pokescripting::AbilityWrapper* ability) +{ + const Pokemod::Script script = ability->battleScript(); + Kross::Action* abilityScript = new Kross::Action(Kross::Manager::self().actionCollection()->collection("ability"), QString("ability-%1").arg(QUuid::createUuid().toString())); + abilityScript->setInterpreter(script.interpreter()); + abilityScript->setCode(script.script().toUtf8()); + abilityScript->addObject(this, "owner", Kross::ChildrenInterface::AutoConnectSignals); + abilityScript->trigger(); + m_abilities[ability] = abilityScript; +} + +void Pokebattle::TeamMember::initItems() +{ + Pokemod::Hat<Pokescripting::ItemWrapper*> hat = m_species->itemHat(); + for (int i = 0; i < pokemod()->rules()->maxHeldItems(); ++i) + { + if (m_species->itemChance().poll()) + m_items.append(hat.pick()); + } +} + +void Pokebattle::TeamMember::initAbilities(const QList<Pokescripting::AbilityWrapper*>& initial) +{ + foreach (Pokescripting::AbilityWrapper* ability, initial) + initAbility(ability); + Pokemod::Hat<Pokescripting::AbilityWrapper*> hat = m_species->abilityHat(); + while (m_abilities.size() < pokemod()->rules()->maxAbilities()) + { + Pokescripting::AbilityWrapper* ability = hat.takeAndClear(); + if (!m_abilities.contains(ability)) + initAbility(ability); + } +} + +void Pokebattle::TeamMember::initMoves(const QList<Pokescripting::MoveWrapper*>& initial) +{ + m_moves = initial; + for (int i = 0; (i < m_species->moveCount()) && (m_moves.size() < pokemod()->rules()->maxMoves()); ++i) + { + Pokescripting::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 Pokebattle::TeamMember::initNatures(const QList<Pokescripting::NatureWrapper*>& initial) +{ + m_natures = initial; + Pokemod::Hat<Pokescripting::NatureWrapper*> hat = pokemod()->natureHat(); + while (m_natures.size() < pokemod()->rules()->maxNatures()) + { + Pokescripting::NatureWrapper* nature = hat.takeAndClear(); + if (!m_natures.contains(nature)) + m_natures.append(nature); + } +} + +void Pokebattle::TeamMember::initStats() +{ + if (pokemod()->rules()->specialDVSplit()) + { + for (int i = 0; i < Pokemod::ST_End_GSC; ++i) + m_dv[i] = qrand() & 31; + } + else + { + for (int i = Pokemod::ST_No_HP_Start; i < Pokemod::ST_End_RBY; ++i) + m_dv[i] = qrand() & 15; + m_dv[Pokemod::ST_HP] = ((m_dv[Pokemod::ST_Attack] & 1) << 3) + ((m_dv[Pokemod::ST_Defense] & 1) << 2) + ((m_dv[Pokemod::ST_Speed] & 1) << 1) + (m_dv[Pokemod::ST_Special] & 1); + } +} diff --git a/sigbattle/TeamMember.h b/sigbattle/TeamMember.h new file mode 100644 index 00000000..db61571a --- /dev/null +++ b/sigbattle/TeamMember.h @@ -0,0 +1,207 @@ +/* + * 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/>. + */ + +#ifndef __POKEBATTLE_TEAMMEMBER__ +#define __POKEBATTLE_TEAMMEMBER__ + +// Pokebattle includes +#include "Global.h" + +// Pokescripting includes +#include "../pokescripting/Config.h" + +// Pokemod includes +#include "../pokemod/Global.h" + +// Qt includes +#include <QtCore/QFuture> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QMultiMap> +#include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QString> +#include <QtCore/QUuid> + +// Forward declarations +namespace Pokescripting +{ +class AbilityWrapper; +class ItemWrapper; +class MoveWrapper; +class NatureWrapper; +class MapTrainerTeamMemberWrapper; +class PokemodWrapper; +class SpeciesWrapper; +class StatusWrapper; +} +namespace Kross +{ +class Action; +} + +namespace Pokebattle +{ +class Arena; +class Containment; + +class POKEBATTLE_EXPORT TeamMember : public Pokescripting::Config +{ + Q_OBJECT + + public: + enum Gender + { + Male = 0, + Female = 1, + Genderless = 2 + }; + + enum ActionType + { + Attack = 0, + Item = 1, + Switch = 2, + Run = 3, + Skip = 4, + Timeout = 5, + Invalid = 6 + }; + + typedef QList<QUuid> Targets; + typedef QPair<QVariant, Targets> ActionData; + typedef QPair<ActionType, ActionData> Action; + typedef QPair<TeamMember*, QFuture<TeamMember::Action> > RequestedAction; + + TeamMember(const int speciesId, const QString& name, const int level, Containment* containment, const bool suppressItems = false); + TeamMember(Pokescripting::MapTrainerTeamMemberWrapper* teamMember, Containment* containment); + + QUuid id() const; + + QString name() const; + long long currentHp() const; + Pokescripting::SpeciesWrapper* species() const; + int level() const; + Gender gender() const; + long long levelExperience() const; + int baseStat(const Pokemod::Stat stat) const; + long long statExperience(const Pokemod::Stat stat) const; + int dv(const Pokemod::Stat stat) const; + long long statValue(const Pokemod::Stat stat, const long long exp = -1) const; + long long calcExp(int level = -1) const; + + bool canLearnMove(Pokescripting::MoveWrapper* move) const; + + Pokescripting::PokemodWrapper* pokemod() const; + signals: + void speciesChanged(Pokescripting::SpeciesWrapper* species); + + void evolveStart(); + void evolveEnd(); + + void nameChanged(const QString& oldName, const QString& newName); + + void statusCured(Pokescripting::StatusWrapper* status); + void statusInflicted(Pokescripting::StatusWrapper* status); + + void expGained(const int exp); + void levelAboutToGrow(); + void levelGrown(const int newLevel); + + void statChanged(const Pokemod::Stat stat, const int value); + void effortFull(const int stat); + void totalEffortFull(); + + void itemTaken(Pokescripting::ItemWrapper* item); + void itemGiven(Pokescripting::ItemWrapper* item); + + void moveForgotten(Pokescripting::MoveWrapper* move); + void moveLearned(Pokescripting::MoveWrapper* move); + void movesFull(Pokescripting::MoveWrapper* move); + void unlearnableMove(Pokescripting::MoveWrapper* move); + + void knockedOut(); + public slots: + void boostLevels(const int levels); + + void evolveInto(Pokescripting::SpeciesWrapper* newSpecies); + + void setName(const QString& name); + void cureStatus(Pokescripting::StatusWrapper* status); + void giveStatus(Pokescripting::StatusWrapper* status); + void giveLevelExp(const int exp); + void giveStatExp(const Pokemod::Stat stat, const int exp); + void takeItem(Pokescripting::ItemWrapper* item); + void giveItem(Pokescripting::ItemWrapper* item); + void forgetMove(Pokescripting::MoveWrapper* move); + void teachMove(Pokescripting::MoveWrapper* move); + + Action requestAction() const; + + void makeActive(Arena* arena); + + virtual void writeBack(); + protected slots: + void setSpecies(Pokescripting::SpeciesWrapper* species); + void setLevel(const int level); + private slots: + void levelGrown(); + protected: + Containment* m_containment; + + const QUuid m_id; + + QString m_name; + long long m_currentHp; + Pokescripting::SpeciesWrapper* m_species; + Gender m_gender; + long long m_levelExp; + int m_level; + long long m_statExp[Pokemod::ST_End_GSC]; + int m_dv[Pokemod::ST_End_GSC]; + QMultiMap<Pokescripting::StatusWrapper*, Kross::Action*> m_status; + QMap<Pokescripting::AbilityWrapper*, Kross::Action*> m_abilities; + QList<Pokescripting::ItemWrapper*> m_items; + QList<Pokescripting::MoveWrapper*> m_moves; + QList<Pokescripting::NatureWrapper*> m_natures; + + QList<Kross::Action*> m_abilityBattleScripts; + QList<Kross::Action*> m_statusBattleScripts; + private: + void makeConnections(); + + void initAbility(Pokescripting::AbilityWrapper* ability); + + void initItems(); + void initAbilities(const QList<Pokescripting::AbilityWrapper*>& initial = QList<Pokescripting::AbilityWrapper*>()); + void initMoves(const QList<Pokescripting::MoveWrapper*>& initial = QList<Pokescripting::MoveWrapper*>()); + void initNatures(const QList<Pokescripting::NatureWrapper*>& initial = QList<Pokescripting::NatureWrapper*>()); + void initStats(); +}; + +int actionPriority(const TeamMember* teamMember, const TeamMember::Action& action); + +} +Q_DECLARE_METATYPE(Pokebattle::TeamMember*) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::Gender) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::ActionType) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::Targets) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::ActionData) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::Action) +Q_DECLARE_METATYPE(Pokebattle::TeamMember::RequestedAction) + +#endif diff --git a/sigbattle/TurnArena.cpp b/sigbattle/TurnArena.cpp new file mode 100644 index 00000000..bf0bece8 --- /dev/null +++ b/sigbattle/TurnArena.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 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 "TurnArena.h" + +// Pokemod includes +#include "../pokemod/Fraction.h" + +// Qt includes +#include <QtAlgorithms> +#include <QtCore/QtConcurrentMap> +#include <QtCore/QFuture> +#include <QtCore/QTimer> + +bool Pokebattle::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(Pokemod::ST_Speed); + const int speed2 = reqAction2.first->statValue(Pokemod::ST_Speed); + if (speed1 < speed2) + return true; + else if (speed1 == speed2) + return Pokemod::Fraction(1, 2).poll(); + } + return false; +} + +Pokebattle::TurnArena::TurnArena(QList<Player*> players, QObject* parent) : + Arena(players, parent), + m_watcher(new QFutureWatcher<TeamMember::RequestedAction>(this)), + m_timer(new QTimer(this)) +{ + setupBattle(); + m_timer->setSingleShot(true); + connect(m_timer, SIGNAL(timeout()), m_watcher, SLOT(cancel())); +} + +void Pokebattle::TurnArena::processRound() +{ + emit(roundAboutToStart()); + emit(roundStart()); + QFuture<TeamMember::RequestedAction> reqActions = QtConcurrent::mapped(active(), &Pokebattle::requestDecision); + m_watcher->setFuture(reqActions); + m_timer->start(120000); + reqActions.waitForFinished(); + m_timer->stop(); + QList<TeamMember::RequestedAction> actions = reqActions.results(); + qStableSort(actions.begin(), actions.end(), sortActions); + for (int i = 0; i < actions.size(); ++i) + { + for (int j = 0; j < i; ++j) + { + + // TODO: Notify scripts of the moves before it and of its targets + } + } + // TODO: notify all attacks of what is going on in order (they can change priorities as needed) + qStableSort(actions.begin(), actions.end(), sortActions); + foreach (TeamMember::RequestedAction action, actions) + { + // TODO: Handle when the target switches or is knocked out + if (action.first->currentHp()) + handleAction(action.first, action.second); + } + emit(roundAboutToEnd()); + emit(roundEnd()); + if (numActiveTeams() <= 1) + { + // TODO: End Round + } + else + processRound(); +} + +void Pokebattle::TurnArena::setupBattle() +{ + // TODO: setup everything for the arena to do with the turns + Arena::setupBattle(); +} diff --git a/sigbattle/TurnArena.h b/sigbattle/TurnArena.h new file mode 100644 index 00000000..636ae501 --- /dev/null +++ b/sigbattle/TurnArena.h @@ -0,0 +1,59 @@ +/* + * Copyright 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/>. + */ + +#ifndef __POKEBATTLE_TURNARENA__ +#define __POKEBATTLE_TURNARENA__ + +// Pokebattle includes +#include "Arena.h" +#include "TeamMember.h" + +// Qt includes +#include <QtCore/QFutureWatcher> + +// Forward declarations +class QTimer; + +namespace Pokebattle +{ +class POKEBATTLE_EXPORT TurnArena : public Arena +{ + Q_OBJECT + + public: + TurnArena(QList<Player*> players, QObject* parent); + signals: + void roundAboutToStart(); + void roundStart(); + void roundAboutToEnd(); + void roundEnd(); + public slots: + protected slots: + void processRound(); + protected: + void setupBattle(); + private: + QFutureWatcher<TeamMember::RequestedAction>* m_watcher; + QTimer* m_timer; +}; + +bool sortActions(const TeamMember::RequestedAction& reqAction1, const TeamMember::RequestedAction& reqAction2); + +} +Q_DECLARE_METATYPE(Pokebattle::TurnArena*) + +#endif |