]> git.localhorst.tv Git - l2e.git/blob - src/battle/states/PerformAttacks.cpp
added complex attack and spell animations
[l2e.git] / src / battle / states / PerformAttacks.cpp
1 /*
2  * PerformAttacks.cpp
3  *
4  *  Created on: Aug 10, 2012
5  *      Author: holy
6  */
7
8 #include "PerformAttacks.h"
9
10 #include "../BattleState.h"
11 #include "../Hero.h"
12 #include "../Monster.h"
13 #include "../../app/Application.h"
14 #include "../../app/Input.h"
15 #include "../../common/Ikari.h"
16 #include "../../common/Item.h"
17 #include "../../common/Spell.h"
18 #include "../../geometry/operators.h"
19 #include "../../geometry/Point.h"
20 #include "../../graphics/Animation.h"
21 #include "../../graphics/Font.h"
22 #include "../../graphics/Frame.h"
23
24 #include <cstring>
25
26 using app::Application;
27 using app::Input;
28 using geometry::Point;
29 using geometry::Vector;
30
31 namespace battle {
32
33 void PerformAttacks::EnterState(Application &c, SDL_Surface *screen) {
34         ctrl = &c;
35 }
36
37 void PerformAttacks::ExitState(Application &c, SDL_Surface *screen) {
38         ctrl = 0;
39 }
40
41 void PerformAttacks::ResumeState(Application &ctrl, SDL_Surface *screen) {
42         fakeMoveTimer = GraphicsTimers().StartCountdown(850);
43 }
44
45 void PerformAttacks::PauseState(Application &ctrl, SDL_Surface *screen) {
46
47 }
48
49
50 void PerformAttacks::Resize(int width, int height) {
51
52 }
53
54
55 void PerformAttacks::HandleEvents(const Input &input) {
56         if (fakeMoveTimer.JustHit()) {
57                 if (monsters) {
58                         if (titleBarText) {
59                                 titleBarText = 0;
60                                 ++cursor;
61                                 while (cursor < battle->MaxMonsters() && !battle->MonsterPositionOccupied(cursor)) {
62                                         ++cursor;
63                                 }
64                                 if (cursor >= battle->MaxMonsters()) {
65                                         battle->ClearAllAttacks();
66                                         ctrl->PopState();
67                                 }
68                         } else {
69                                 if (cursor == 0) {
70                                         if (battle->HeroAt(battle->NumHeroes() - 1).AttackAnimation()) {
71                                                 battle->HeroAt(battle->NumHeroes() - 1).AttackAnimation()->Stop();
72                                         }
73                                         if (battle->HeroAt(battle->NumHeroes() - 1).SpellAnimation()) {
74                                                 battle->HeroAt(battle->NumHeroes() - 1).SpellAnimation()->Stop();
75                                         }
76                                 }
77                                 titleBarText = battle->MonsterAt(cursor).Name();
78                         }
79                 } else {
80                         const AttackChoice &ac(battle->AttackChoiceAt(cursor));
81                         if (titleBarText) {
82                                 titleBarText = 0;
83
84                                 switch (ac.GetType()) {
85                                         case AttackChoice::SWORD:
86                                                 if (battle->HeroAt(cursor).AttackAnimation()) {
87                                                         battle->HeroAt(cursor).AttackAnimation()->Start(*this);
88                                                 }
89                                                 break;
90                                         case AttackChoice::MAGIC:
91                                                 if (battle->HeroAt(cursor).SpellAnimation()) {
92                                                         battle->HeroAt(cursor).SpellAnimation()->Start(*this);
93                                                 }
94                                                 break;
95                                         case AttackChoice::DEFEND:
96                                                 break;
97                                         case AttackChoice::IKARI:
98                                                 if (ac.GetItem()->HasIkari()) {
99                                                         if (ac.GetItem()->GetIkari()->IsMagical()) {
100                                                                 if (battle->HeroAt(cursor).SpellAnimation()) {
101                                                                         battle->HeroAt(cursor).SpellAnimation()->Start(*this);
102                                                                 }
103                                                         } else {
104                                                                 if (battle->HeroAt(cursor).AttackAnimation()) {
105                                                                         battle->HeroAt(cursor).AttackAnimation()->Start(*this);
106                                                                 }
107                                                         }
108                                                 }
109                                                 break;
110                                         case AttackChoice::ITEM:
111                                                 break;
112                                         case AttackChoice::UNDECIDED:
113                                                 break;
114                                 }
115
116                                 ++cursor;
117                                 if (cursor == battle->NumHeroes()) {
118                                         cursor = 0;
119                                         monsters = true;
120                                 }
121                         } else {
122                                 if (cursor > 0) {
123                                         if (battle->HeroAt(cursor - 1).AttackAnimation()) {
124                                                 battle->HeroAt(cursor - 1).AttackAnimation()->Stop();
125                                         }
126                                         if (battle->HeroAt(cursor - 1).SpellAnimation()) {
127                                                 battle->HeroAt(cursor - 1).SpellAnimation()->Stop();
128                                         }
129                                 }
130                                 switch (ac.GetType()) {
131                                         case AttackChoice::SWORD:
132                                                 titleBarText = battle->HeroAt(cursor).HasWeapon() ? battle->HeroAt(cursor).Weapon()->Name() : "Gauntlet";
133                                                 break;
134                                         case AttackChoice::MAGIC:
135                                                 titleBarText = ac.GetSpell()->Name();
136                                                 break;
137                                         case AttackChoice::DEFEND:
138                                                 titleBarText = "Defends.";
139                                                 break;
140                                         case AttackChoice::IKARI:
141                                                 titleBarText = ac.GetItem()->HasIkari() ? ac.GetItem()->GetIkari()->Name() : "No Ikari?";
142                                                 break;
143                                         case AttackChoice::ITEM:
144                                                 titleBarText = ac.GetItem()->Name();
145                                                 break;
146                                         case AttackChoice::UNDECIDED:
147                                                 titleBarText = "WTF???";
148                                                 break;
149                                 }
150                         }
151                 }
152         }
153 }
154
155
156 void PerformAttacks::UpdateWorld(float deltaT) {
157
158 }
159
160 void PerformAttacks::Render(SDL_Surface *screen) {
161         Vector<int> offset(battle->CalculateScreenOffset(screen));
162         battle->RenderBackground(screen, offset);
163         battle->RenderMonsters(screen, offset);
164         battle->RenderHeroes(screen, offset);
165         battle->RenderSmallHeroTags(screen, offset);
166         RenderTitleBar(screen, offset);
167 }
168
169 void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector<int> &offset) {
170         if (!titleBarText) return;
171
172         int height(battle->Res().titleFrame->BorderHeight() * 2 + battle->Res().titleFont->CharHeight());
173         battle->Res().titleFrame->Draw(screen, Point<int>(offset.X(), offset.Y()), battle->BackgroundWidth(), height);
174
175         Point<int> textPosition(
176                         (battle->BackgroundWidth() - (std::strlen(titleBarText) * battle->Res().titleFont->CharWidth())) / 2,
177                         battle->Res().titleFrame->BorderHeight());
178         battle->Res().titleFont->DrawString(titleBarText, screen, textPosition + offset);
179 }
180
181 }