--- /dev/null
+#ifndef BATTLE_BATTLE_H_
+#define BATTLE_BATTLE_H_
+
+namespace battle {
+ class Hero;
+ class Monster;
+ class PartyLayout;
+ class TargetSelection;
+}
+namespace common {
+ class Stats;
+}
+
+#include "Capsule.h"
+#include "Hero.h"
+#include "Monster.h"
+
+#include <vector>
+#include <SDL.h>
+
+
+namespace battle {
+
+/// This class models a battle between a party of monsters and one
+/// of heroes.
+/// See http://luke.redirectme.net/redmine/projects/l2e/wiki/Battle for
+/// an explanation of how to use this interface.
+class Battle {
+
+public:
+ Battle(const PartyLayout *heroesLayout, const PartyLayout *monstersLayout);
+
+public:
+ void AddHero(const Hero &);
+ void AddMonster(const Monster &);
+ void SetCapsule(const Capsule &);
+
+ int NumHeroes() const;
+ int MaxHeroes() const;
+ int NumMonsters() const;
+ int MaxMonsters() const;
+ bool HasCapsule() const;
+
+ bool HeroPositionOccupied(int index) const;
+ bool HeroAlive(int index) const;
+ bool MonsterPositionOccupied(int index) const;
+ bool MonsterAlive(int index) const;
+ bool CapsuleAlive() const;
+
+ std::vector<Hero>::const_iterator HeroesBegin() const { return heroes.begin(); }
+ std::vector<Hero>::const_iterator HeroesEnd() const { return heroes.end(); }
+ Hero &HeroAt(int index);
+ const Hero &HeroAt(int index) const;
+
+ std::vector<Monster>::const_iterator MonstersBegin() const { return monsters.begin(); }
+ std::vector<Monster>::const_iterator MonstersEnd() const { return monsters.end(); }
+ Monster &MonsterAt(int index);
+ const Monster &MonsterAt(int index) const;
+
+ Capsule &GetCapsule() { return capsule; }
+ const Capsule &GetCapsule() const { return capsule; }
+
+ const PartyLayout &HeroesLayout() const { return *heroesLayout; }
+ const PartyLayout &MonstersLayout() const { return *monstersLayout; }
+
+ void NextHero();
+ bool BeforeFirstHero() const { return activeHero < 0; }
+ void PreviousHero();
+ void SwapHeroes(int lhs, int rhs);
+ Hero &ActiveHero() { return HeroAt(activeHero); }
+ const Hero &ActiveHero() const { return HeroAt(activeHero); }
+ bool IsActiveHero(int index) const { return index == activeHero; }
+ bool HasChosenAttackType() const;
+ bool AttackSelectionDone() const;
+
+ struct Order {
+ enum Performer {
+ HERO,
+ CAPSULE,
+ MONSTER,
+ };
+ Order(Performer by, int index = 0)
+ : index(index), by(by) { }
+ AttackChoice &GetAttackChoice(Battle &) const;
+ common::Stats &GetStats(Battle &) const;
+ bool IsHero() const { return by == HERO; }
+ bool IsCapsule() const { return by == CAPSULE; }
+ bool IsMonster() const { return by == MONSTER; }
+ int index;
+ Performer by;
+ };
+
+ void CalculateAttackOrder();
+ void NextAttack();
+ bool AttacksFinished() const;
+ void CalculateDamage();
+ void ApplyDamage();
+ const Order &CurrentAttack() const;
+ AttackChoice &CurrentAttackAttackChoice();
+ void ClearAllAttacks();
+
+ void DecideMonsterAttack(Monster &);
+ void DecideCapsuleAttack();
+ void CalculateDamage(const common::Stats &attackerStats, TargetSelection &targets) const;
+ Uint16 CalculateDamage(const common::Stats &attacker, const common::Stats &defender) const;
+
+ bool Victory() const;
+ bool Defeat() const;
+
+private:
+ const PartyLayout *heroesLayout;
+ const PartyLayout *monstersLayout;
+ std::vector<Hero> heroes;
+ std::vector<Monster> monsters;
+ Capsule capsule;
+
+ int activeHero;
+
+ std::vector<Order> attackOrder;
+ int attackCursor;
+
+ int expReward;
+ int goldReward;
+
+};
+
+}
+
+#endif