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