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