]> git.localhorst.tv Git - l2e.git/blob - src/menu/CapsuleChangeMenu.cpp
more intuitive horizontal capsule class navigation
[l2e.git] / src / menu / CapsuleChangeMenu.cpp
1 #include "CapsuleChangeMenu.h"
2
3 #include "CapsuleMenu.h"
4 #include "Resources.h"
5 #include "../app/Application.h"
6 #include "../app/Input.h"
7 #include "../common/Inventory.h"
8 #include "../common/Item.h"
9 #include "../common/GameConfig.h"
10 #include "../common/GameState.h"
11 #include "../graphics/Font.h"
12 #include "../graphics/Frame.h"
13 #include "../graphics/Texture.h"
14
15 using app::Input;
16 using common::Capsule;
17 using common::Inventory;
18 using common::Item;
19 using geometry::Vector;
20 using graphics::Font;
21 using graphics::Frame;
22
23 namespace menu {
24
25 CapsuleChangeMenu::CapsuleChangeMenu(CapsuleMenu *parent)
26 : parent(parent) {
27
28 }
29
30
31 void CapsuleChangeMenu::OnEnterState(SDL_Surface *) {
32
33 }
34
35 void CapsuleChangeMenu::OnExitState(SDL_Surface *) {
36
37 }
38
39 void CapsuleChangeMenu::OnResumeState(SDL_Surface *) {
40
41 }
42
43 void CapsuleChangeMenu::OnPauseState(SDL_Surface *) {
44
45 }
46
47
48 void CapsuleChangeMenu::OnResize(int width, int height) {
49
50 }
51
52
53 void CapsuleChangeMenu::HandleEvents(const Input &input) {
54         if (input.JustPressed(Input::ACTION_B)) {
55                 Ctrl().PopState();
56         }
57
58         if (input.JustPressed(Input::PAD_UP)) {
59                 NextClass();
60         }
61         if (input.JustPressed(Input::PAD_RIGHT)) {
62                 NextCapsule();
63         }
64         if (input.JustPressed(Input::PAD_DOWN)) {
65                 PreviousClass();
66         }
67         if (input.JustPressed(Input::PAD_LEFT)) {
68                 PreviousCapsule();
69         }
70 }
71
72 void CapsuleChangeMenu::NextCapsule() {
73         int storedClass = parent->Game().state->GetCapsule().ClassIndex();
74         int &index = parent->Game().state->capsule;
75         ++index;
76         index %= parent->Game().state->NumCapsules();
77         // skip unexplored
78         while (parent->Game().state->GetCapsule().MaxClass() <= 0) {
79                 ++index;
80                 index %= parent->Game().state->NumCapsules();
81         }
82         parent->Game().state->GetCapsule().SetClass(storedClass);
83 }
84
85 void CapsuleChangeMenu::PreviousCapsule() {
86         int storedClass = parent->Game().state->GetCapsule().ClassIndex();
87         int &index = parent->Game().state->capsule;
88         --index;
89         if (index < 0) index += parent->Game().state->NumCapsules();
90         // skip unexplored
91         while (GetCapsule().MaxClass() <= 0) {
92                 --index;
93                 if (index < 0) index += parent->Game().state->NumCapsules();
94         }
95         parent->Game().state->GetCapsule().SetClass(storedClass);
96 }
97
98 void CapsuleChangeMenu::NextClass() {
99         GetCapsule().NextClass();
100 }
101
102 void CapsuleChangeMenu::PreviousClass() {
103         GetCapsule().PreviousClass();
104 }
105
106
107 void CapsuleChangeMenu::UpdateWorld(float deltaT) {
108
109 }
110
111 void CapsuleChangeMenu::Render(SDL_Surface *screen) {
112         const Font &font(*parent->Res().statusFont);
113         const Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
114         const Vector<int> capsuleOffset(
115                         6 * font.CharWidth(),
116                         12 * font.CharHeight());
117         const Vector<int> infoOffset(
118                         12 * font.CharWidth(),
119                         2 * font.CharHeight() - font.CharHeight() / 8);
120         // TODO: wheel offset: top left, center, or center bottom?
121         const Vector<int> wheelOffset(
122                         6 * font.CharWidth(),
123                         19 * font.CharHeight() - font.CharHeight() / 8);
124         const Vector<int> classesOffset(
125                         12 * font.CharWidth(),
126                         13 * font.CharHeight() - font.CharHeight() / 8);
127         const Vector<int> menuOffset(
128                         font.CharWidth(),
129                         24 * font.CharHeight() - font.CharHeight() / 8);
130
131         parent->RenderBackground(screen);
132         parent->RenderCapsule(screen, offset + capsuleOffset);
133         parent->RenderInfo(screen, offset + infoOffset);
134         parent->RenderWheel(screen, offset + wheelOffset);
135         RenderClasses(screen, offset + classesOffset);
136         parent->RenderMenu(screen, offset + menuOffset);
137 }
138
139 void CapsuleChangeMenu::RenderClasses(SDL_Surface *screen, const Vector<int> &offset) const {
140         Vector<int> cursor(offset);
141
142         int numClasses = 0;
143         for (int i = 0; i < parent->Game().state->NumCapsules(); ++i) {
144                 if (numClasses < parent->Game().state->capsules[i].NumClasses()) {
145                         numClasses = parent->Game().state->capsules[i].NumClasses();
146                 }
147         }
148
149         parent->Res().capsuleSelectTopLeft->Draw(screen, cursor);
150         cursor.Y() += parent->Res().capsuleSelectTopLeft->Height();
151         Vector<int> target(
152                         cursor.X() + parent->Res().capsuleSelectTopLeft->Width(),
153                         cursor.Y() + numClasses * parent->Res().capsuleSelectLadder->Height());
154         parent->Res().capsuleSelectLeftRepeat->Render(screen, cursor, target);
155         cursor.Y() = target.Y();
156         parent->Res().capsuleSelectBottomLeft->Draw(screen, cursor);
157         cursor.X() += parent->Res().capsuleSelectTopLeft->Width();
158
159         for (int i = 0; i < parent->Game().state->NumCapsules(); ++i) {
160                 cursor.Y() = offset.Y();
161                 parent->Res().capsuleSelectTopRepeat->Draw(screen, cursor);
162                 cursor.Y() += parent->Res().capsuleSelectTopRepeat->Height();
163                 for (int j = numClasses - 1; j >= 0; --j) {
164                         parent->Res().capsuleSelectLadder->Draw(
165                                         screen, cursor,
166                                         j < parent->Game().state->capsules[i].MaxClass(), j);
167                         if (i == parent->Game().state->capsule
168                                         && parent->Game().state->capsules[i].CurrentClass() == j) {
169                                 parent->Res().capsuleSelectCursor->Draw(screen, cursor);
170                         }
171                         cursor.Y() += parent->Res().capsuleSelectLadder->Height();
172                 }
173                 parent->Res().capsuleSelectBottomRepeat->Draw(screen, cursor);
174                 if (parent->Game().state->capsules[i].AlignmentSprite()) {
175                         parent->Game().state->capsules[i].AlignmentSprite()->Draw(screen, cursor);
176                 }
177                 cursor.X() += parent->Res().capsuleSelectLadder->Width();
178         }
179
180         cursor.Y() = offset.Y();
181         parent->Res().capsuleSelectTopRight->Draw(screen, cursor);
182         cursor.Y() += parent->Res().capsuleSelectTopRight->Height();
183         target = Vector<int>(
184                         cursor.X() + parent->Res().capsuleSelectTopRight->Width(),
185                         cursor.Y() + numClasses * parent->Res().capsuleSelectLadder->Height());
186         parent->Res().capsuleSelectRightRepeat->Render(screen, cursor, target);
187         cursor.Y() = target.Y();
188         parent->Res().capsuleSelectBottomRight->Draw(screen, cursor);
189 }
190
191
192 int CapsuleChangeMenu::Width() const {
193         return parent->Width();
194 }
195
196 int CapsuleChangeMenu::Height() const {
197         return parent->Height();
198 }
199
200 Capsule &CapsuleChangeMenu::GetCapsule() {
201         return parent->GetCapsule();
202 }
203
204 const Capsule &CapsuleChangeMenu::GetCapsule() const {
205         return parent->GetCapsule();
206 }
207
208 }