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