]> git.localhorst.tv Git - l2e.git/blob - src/menu/SpellMenu.cpp
added capsule attack/animation handling
[l2e.git] / src / menu / SpellMenu.cpp
1 #include "SpellMenu.h"
2
3 #include "HeroStatus.h"
4 #include "PartyMenu.h"
5 #include "Resources.h"
6 #include "../app/Application.h"
7 #include "../app/Input.h"
8 #include "../common/GameConfig.h"
9 #include "../common/GameState.h"
10 #include "../common/Hero.h"
11 #include "../common/Spell.h"
12 #include "../graphics/Font.h"
13 #include "../graphics/Frame.h"
14
15 #include <algorithm>
16 #include <SDL.h>
17 #include <vector>
18
19 using app::Input;
20 using common::Hero;
21 using common::Spell;
22 using geometry::Vector;
23 using graphics::Font;
24 using graphics::Frame;
25 using std::vector;
26
27 namespace menu {
28
29 SpellMenu::SpellMenu(PartyMenu *parent, int cursor)
30 : parent(parent)
31 , highlight(0)
32 , cursor(cursor)
33 , actionMenu(*parent->Res().itemMenuProperties)
34 , spellMenu(*parent->Res().spellMenuProperties) {
35         actionMenu.Add(parent->Res().itemMenuUseText, CHOICE_USE);
36         actionMenu.Add(parent->Res().itemMenuSortText, CHOICE_SORT);
37 }
38
39
40 void SpellMenu::OnEnterState(SDL_Surface *) {
41         const HeroStatus &status(parent->GetHeroStatus(0));
42         highlight = SDL_CreateRGBSurface(0, status.Width(), status.Height(), 32, 0xFF000000, 0xFF0000, 0xFF00, 0);
43         SDL_FillRect(highlight, 0, SDL_MapRGB(highlight->format, 0xFF, 0xFF, 0xFF));
44         SDL_SetAlpha(highlight, SDL_SRCALPHA|SDL_RLEACCEL, 0x20);
45
46         actionMenu.SetSelected();
47         LoadSpells();
48 }
49
50 void SpellMenu::LoadSpells() {
51         spellMenu.Clear();
52         // TODO: set to max spells once implementation is changed
53         spellMenu.Reserve(GetHero().Spells().size());
54         for (vector<const Spell *>::const_iterator
55                         i = GetHero().Spells().begin(), end = GetHero().Spells().end();
56                         i != end; ++i) {
57                 const Spell *spell = *i;
58                 spellMenu.Add(spell->Name(), spell, spell->CanUseOnStatusScreen(), 0, spell->Cost());
59         }
60 }
61
62 const Hero &SpellMenu::GetHero() const {
63         return *parent->Game().state->party[cursor];
64 }
65
66 Hero &SpellMenu::GetHero() {
67         return *parent->Game().state->party[cursor];
68 }
69
70 void SpellMenu::OnExitState(SDL_Surface *) {
71         SDL_FreeSurface(highlight);
72 }
73
74 void SpellMenu::OnResumeState(SDL_Surface *) {
75
76 }
77
78 void SpellMenu::OnPauseState(SDL_Surface *) {
79
80 }
81
82
83 void SpellMenu::OnResize(int width, int height) {
84
85 }
86
87
88 void SpellMenu::HandleEvents(const Input &input) {
89         if (actionMenu.IsActive()) {
90                 if (input.JustPressed(Input::PAD_LEFT)) {
91                         actionMenu.PreviousItem();
92                 }
93                 if (input.JustPressed(Input::PAD_RIGHT)) {
94                         actionMenu.NextItem();
95                 }
96         } else {
97                 if (input.JustPressed(Input::PAD_UP)) {
98                         spellMenu.PreviousRow();
99                 }
100                 if (input.JustPressed(Input::PAD_RIGHT)) {
101                         spellMenu.NextItem();
102                 }
103                 if (input.JustPressed(Input::PAD_DOWN)) {
104                         spellMenu.NextRow();
105                 }
106                 if (input.JustPressed(Input::PAD_LEFT)) {
107                         spellMenu.PreviousItem();
108                 }
109         }
110
111         if (input.JustPressed(Input::ACTION_A)) {
112                 if (actionMenu.IsActive()) {
113                         if (actionMenu.Selected() == CHOICE_SORT) {
114                                 std::sort(GetHero().Spells().begin(),
115                                                 GetHero().Spells().end(),
116                                                 Spell::Less);
117                                 LoadSpells();
118                         } else {
119                                 actionMenu.SetSelected();
120                                 spellMenu.SetActive();
121                         }
122                 } else if (spellMenu.IsActive()) {
123                         spellMenu.SetDualSelection();
124                 } else if (spellMenu.SelectedIndex() == spellMenu.SecondaryIndex()) {
125                         if (spellMenu.Selected()->CanUseOnStatusScreen()) {
126                                 // TODO: use spell
127                         }
128                 } else {
129                         std::swap(GetHero().Spells().at(spellMenu.SelectedIndex()),
130                                         GetHero().Spells().at(spellMenu.SecondaryIndex()));
131                         spellMenu.SwapSelected();
132                         spellMenu.SetActive();
133                 }
134         }
135
136         if (input.JustPressed(Input::ACTION_B)) {
137                 if (actionMenu.IsActive()) {
138                         Ctrl().PopState();
139                 } else if (spellMenu.IsActive()) {
140                         actionMenu.SetActive();
141                         spellMenu.SetInactive();
142                 } else {
143                         spellMenu.SetActive();
144                 }
145         }
146 }
147
148 void SpellMenu::UpdateWorld(float deltaT) {
149
150 }
151
152 void SpellMenu::Render(SDL_Surface *screen) {
153         const Font &font(*parent->Res().normalFont);
154         Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
155         Vector<int> menuOffset(font.CharWidth(), 13 * font.CharHeight() + font.CharHeight() / 8);
156         Vector<int> spellsOffset(font.CharWidth(), 16 * font.CharHeight() + font.CharHeight() / 8);
157
158         parent->RenderBackground(screen);
159         RenderHighlight(screen, offset);
160         parent->RenderHeros(screen, offset);
161         RenderMenu(screen, menuOffset + offset);
162         RenderSpells(screen, spellsOffset + offset);
163 }
164
165 int SpellMenu::Width() const {
166         return parent->Width();
167 }
168
169 int SpellMenu::Height() const {
170         return parent->Height();
171 }
172
173 void SpellMenu::RenderHighlight(SDL_Surface *screen, const Vector<int> &offset) const {
174         if (cursor < 0) return;
175         Vector<int> statusOffset(parent->StatusOffset(cursor));
176         statusOffset -= Vector<int>(0, parent->Res().normalFont->CharHeight() / 8);
177         SDL_Rect rect;
178         rect.x = statusOffset.X();
179         rect.y = statusOffset.Y();
180         SDL_BlitSurface(highlight, 0, screen, &rect);
181 }
182
183 void SpellMenu::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) const {
184         const Font &font(*parent->Res().normalFont);
185         const Frame &frame(*parent->Res().statusFrame);
186
187         const Vector<int> labelOffset(2 * font.CharWidth(), font.CharHeight());
188         const Vector<int> menuFrameOffset(offset.X() + 9 * font.CharWidth(), offset.Y());
189         const Vector<int> menuOffset(menuFrameOffset.X() + 3 * font.CharWidth(), menuFrameOffset.Y() + font.CharHeight());
190
191         frame.Draw(screen, offset, 9 * font.CharWidth(), 3 * font.CharHeight());
192         font.DrawString(parent->Res().mainMenuSpellText, screen, labelOffset + offset);
193         frame.Draw(screen, menuFrameOffset, 21 * font.CharWidth(), 3 * font.CharHeight());
194         actionMenu.Draw(screen, menuOffset);
195 }
196
197 void SpellMenu::RenderSpells(SDL_Surface *screen, const Vector<int> &offset) const {
198         const Font &font(*parent->Res().normalFont);
199         const Frame &frame(*parent->Res().statusFrame);
200         const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 4);
201
202         frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
203         spellMenu.Draw(screen, offset + menuOffset);
204 }
205
206 }