]> git.localhorst.tv Git - l2e.git/blob - src/battle/BattleState.h
added "profile" build configuration
[l2e.git] / src / battle / BattleState.h
1 #ifndef BATTLE_BATTLESTATE_H_
2 #define BATTLE_BATTLESTATE_H_
3
4 namespace battle {
5         class PartyLayout;
6 }
7 namespace common {
8         class Item;
9         struct GameConfig;
10 }
11 namespace math {
12         template<class>
13         class Vector;
14 }
15
16 #include "AttackTypeMenu.h"
17 #include "Capsule.h"
18 #include "Hero.h"
19 #include "HeroTag.h"
20 #include "Monster.h"
21 #include "MoveMenu.h"
22 #include "Resources.h"
23 #include "SmallHeroTag.h"
24 #include "../app/State.h"
25 #include "../common/GameConfig.h"
26 #include "../common/Stats.h"
27 #include "../graphics/Animation.h"
28 #include "../graphics/Menu.h"
29
30 #include <cassert>
31 #include <vector>
32 #include <SDL.h>
33
34 namespace battle {
35
36 class BattleState
37 : public app::State {
38
39 public:
40         BattleState(common::GameConfig *game, SDL_Surface *background, const PartyLayout *monstersLayout)
41         : game(game)
42         , background(background)
43         , monstersLayout(monstersLayout)
44         , heroesLayout(game->heroesLayout)
45         , res(game->battleResources)
46         , attackTypeMenu(res->attackIcons)
47         , moveMenu(res->moveIcons)
48         , numHeroes(0)
49         , activeHero(-1)
50         , attackCursor(-1)
51         , expReward(0)
52         , goldReward(0)
53         , ranAway(false) { assert(background && monstersLayout && game); }
54
55 public:
56         void AddMonster(const Monster &);
57         void AddHero(const Hero &);
58         void SetCapsule(const Capsule &);
59
60 public:
61         virtual void HandleEvents(const app::Input &);
62         virtual void UpdateWorld(Uint32 deltaT);
63         virtual void Render(SDL_Surface *);
64
65 public:
66         const Resources &Res() const { return *res; }
67         AttackTypeMenu &GetAttackTypeMenu() { return attackTypeMenu; }
68         MoveMenu &GetMoveMenu() { return moveMenu; }
69
70         graphics::Menu<const common::Item *> &ItemMenu() { return itemMenu; }
71         const graphics::Menu<const common::Item *> &ItemMenu() const { return itemMenu; }
72
73         void NextHero();
74         bool BeforeFirstHero() const { return activeHero < 0; }
75         void PreviousHero();
76         void SwapHeroes(int lhs, int rhs);
77         Hero &ActiveHero() { assert(activeHero >= 0 && activeHero < NumHeroes()); return heroes[activeHero]; }
78         const Hero &ActiveHero() const { assert(activeHero >= 0 && activeHero < NumHeroes()); return heroes[activeHero]; }
79
80         Hero &HeroAt(int index) { assert(index >= 0 && index < NumHeroes()); return heroes[index]; }
81         const Hero &HeroAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroes[index]; }
82         Monster &MonsterAt(int index) { assert(index >= 0 && index < NumHeroes()); return monsters[index]; }
83         const Monster &MonsterAt(int index) const { assert(index >= 0 && index < NumHeroes()); return monsters[index]; }
84
85         const HeroTag &HeroTagAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroTags[index]; }
86         const math::Vector<int> &HeroTagPositionAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroTagPositions[index]; }
87
88         Capsule &GetCapsule() { return capsule; }
89
90         bool HasChosenAttackType() const { return ActiveHero().GetAttackChoice().GetType() != AttackChoice::UNDECIDED; }
91         bool AttackSelectionDone() const { return activeHero >= numHeroes; }
92
93         int NumHeroes() const { return numHeroes; }
94         int MaxHeroes() const { return 4; }
95         int MaxMonsters() const { return monsters.size(); }
96
97         bool MonsterPositionOccupied(int index) { return index >= 0 && index < int(monsters.size()) && monsters[index].Health() > 0; }
98         bool HeroPositionOccupied(int index) const { return index >= 0 && index < numHeroes; }
99
100         void SetRunaway() { ranAway = true; }
101
102         struct Order {
103                 enum Performer {
104                         HERO,
105                         CAPSULE,
106                         MONSTER,
107                 };
108                 Order(Performer by, int index = 0)
109                 : index(index), by(by) { }
110                 AttackChoice &GetAttackChoice(BattleState &) const;
111                 common::Stats &GetStats(BattleState &) const;
112                 bool IsHero() const { return by == HERO; }
113                 bool IsCapsule() const { return by == CAPSULE; }
114                 bool IsMonster() const { return by == MONSTER; }
115                 int index;
116                 Performer by;
117         };
118
119         void CalculateAttackOrder();
120         void NextAttack();
121         bool AttacksFinished() const;
122         void CalculateDamage();
123         void ApplyDamage();
124         const Order &CurrentAttack() const { assert(attackCursor >= 0 && attackCursor < int(attackOrder.size())); return attackOrder[attackCursor]; };
125         AttackChoice &CurrentAttackAttackChoice();
126         void ClearAllAttacks();
127
128         bool Victory() const;
129         bool Defeat() const;
130
131 public:
132         math::Vector<int> CalculateScreenOffset(SDL_Surface *screen) const {
133                 return math::Vector<int>(
134                                 (screen->w - background->w) / 2,
135                                 (screen->h - background->h) / 2);
136         }
137         int Width() const { return background->w; }
138         int Height() const { return background->h; }
139         math::Vector<int> Size() const { return math::Vector<int>(Width(), Height()); }
140
141         void RenderBackground(SDL_Surface *screen, const math::Vector<int> &offset);
142         void RenderMonsters(SDL_Surface *screen, const math::Vector<int> &offset);
143         void RenderHeroes(SDL_Surface *screen, const math::Vector<int> &offset);
144         void RenderCapsule(SDL_Surface *screen, const math::Vector<int> &offset);
145         void RenderHeroTags(SDL_Surface *screen, const math::Vector<int> &offset);
146         void RenderSmallHeroTags(SDL_Surface *screen, const math::Vector<int> &offset);
147
148 private:
149         virtual void OnEnterState(SDL_Surface *screen);
150         virtual void OnExitState(SDL_Surface *screen);
151         virtual void OnResumeState(SDL_Surface *screen);
152         virtual void OnPauseState(SDL_Surface *screen);
153
154         virtual void OnResize(int width, int height);
155
156 private:
157         void LoadInventory();
158
159         void DecideMonsterAttack(Monster &);
160         void DecideCapsuleAttack();
161         void CalculateDamage(const common::Stats &attackerStats, TargetSelection &targets) const;
162         Uint16 CalculateDamage(const common::Stats &attacker, const common::Stats &defender) const;
163
164 private:
165         common::GameConfig *game;
166         SDL_Surface *background;
167         const PartyLayout *monstersLayout;
168         const PartyLayout *heroesLayout;
169         const Resources *res;
170         AttackTypeMenu attackTypeMenu;
171         MoveMenu moveMenu;
172         std::vector<Monster> monsters;
173         std::vector<Order> attackOrder;
174         Hero heroes[4];
175         graphics::Menu<const common::Item *> itemMenu;
176         HeroTag heroTags[4];
177         SmallHeroTag smallHeroTags[4];
178         math::Vector<int> heroTagPositions[4];
179         math::Vector<int> smallHeroTagPositions[4];
180         Capsule capsule;
181         int numHeroes;
182         int activeHero;
183         int attackCursor;
184         int expReward;
185         int goldReward;
186         bool ranAway;
187
188 };
189
190 }
191
192 #endif