]> git.localhorst.tv Git - l2e.git/blob - StatusMenu.cpp
55ba56eb92487787daf98b08ec12c80eec7930f7
[l2e.git] / StatusMenu.cpp
1 #include "StatusMenu.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/Item.h"
12 #include "../common/Stats.h"
13 #include "../graphics/Font.h"
14 #include "../graphics/Frame.h"
15
16 using app::Input;
17 using common::Hero;
18 using common::Item;
19 using common::Stats;
20 using geometry::Vector;
21 using graphics::Font;
22 using graphics::Frame;
23
24 namespace menu {
25
26 StatusMenu::StatusMenu(PartyMenu *parent, int cursor)
27 : parent(parent)
28 , cursor(cursor)
29 , menu(*parent->Res().statusMenuProperties) {
30         menu.Add(parent->Res().nextLabel, 0);
31         menu.Add(parent->Res().returnLabel, 1);
32 }
33
34
35 void StatusMenu::OnEnterState(SDL_Surface *) {
36
37 }
38
39 void StatusMenu::OnExitState(SDL_Surface *) {
40
41 }
42
43 void StatusMenu::OnResumeState(SDL_Surface *) {
44
45 }
46
47 void StatusMenu::OnPauseState(SDL_Surface *) {
48
49 }
50
51
52 void StatusMenu::OnResize(int width, int height) {
53
54 }
55
56
57 void StatusMenu::HandleEvents(const Input &input) {
58         if (input.JustPressed(Input::SHOULDER_RIGHT)) {
59                 NextHero();
60         }
61         if (input.JustPressed(Input::SHOULDER_LEFT)) {
62                 PreviousHero();
63         }
64
65         if (input.JustPressed(Input::PAD_LEFT)) {
66                 menu.PreviousItem();
67         }
68         if (input.JustPressed(Input::PAD_RIGHT)) {
69                 menu.NextItem();
70         }
71
72         if (input.JustPressed(Input::ACTION_A)) {
73                 if (menu.Selected() == 0) {
74                         NextHero();
75                 } else if (menu.Selected() == 1) {
76                         Ctrl().PopState();
77                 }
78         }
79         if (input.JustPressed(Input::ACTION_B)) {
80                 Ctrl().PopState();
81         }
82 }
83
84 void StatusMenu::UpdateWorld(float deltaT) {
85
86 }
87
88 void StatusMenu::Render(SDL_Surface *screen) {
89         Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
90         Vector<int> shoulderNavOffset(
91                         5 * parent->Res().statusFont->CharWidth(),
92                         parent->Res().statusFont->CharHeight());
93         Vector<int> statsOffset(
94                         4 * parent->Res().statusFont->CharWidth(),
95                         8 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
96         Vector<int> equipOffset(
97                         17 * parent->Res().statusFont->CharWidth(),
98                         4 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
99         Vector<int> experienceOffset(
100                         11 * parent->Res().statusFont->CharWidth(),
101                         17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
102         Vector<int> nextLevelOffset(
103                         11 * parent->Res().statusFont->CharWidth(),
104                         20 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
105         Vector<int> ikariOffset(
106                         17 * parent->Res().statusFont->CharWidth(),
107                         17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
108         Vector<int> menuOffset(
109                         parent->Res().statusFont->CharWidth(),
110                         23 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
111
112         parent->RenderBackground(screen);
113         parent->Res().shoulderNav->Draw(screen, offset + shoulderNavOffset);
114         RenderStatus(screen, offset + parent->StatusOffset(0));
115         RenderStats(screen, offset + statsOffset);
116         RenderEquipment(screen, offset + equipOffset);
117         RenderExperience(screen, experienceOffset);
118         RenderNextLevel(screen, nextLevelOffset);
119         RenderIkari(screen, ikariOffset);
120         RenderMenu(screen, menuOffset);
121 }
122
123 int StatusMenu::Width() const {
124         return parent->Width();
125 }
126
127 int StatusMenu::Height() const {
128         return parent->Height();
129 }
130
131 void StatusMenu::RenderStatus(SDL_Surface *screen, const Vector<int> &offset) const {
132         parent->GetHeroStatus(cursor).Render(screen, offset);
133 }
134
135 void StatusMenu::RenderStats(SDL_Surface *screen, const Vector<int> &offset) const {
136         const Stats &stats(GetHero().GetStats());
137         Vector<int> lineBreak(0, parent->Res().statusFont->CharHeight());
138
139         Vector<int> position(offset);
140         RenderStatsLine(parent->Res().atpLabel, stats.Attack(), screen, position);
141
142         position += lineBreak;
143         RenderStatsLine(parent->Res().dfpLabel, stats.Defense(), screen, position);
144
145         position += lineBreak;
146         RenderStatsLine(parent->Res().strLabel, stats.Strength(), screen, position);
147
148         position += lineBreak;
149         RenderStatsLine(parent->Res().aglLabel, stats.Agility(), screen, position);
150
151         position += lineBreak;
152         RenderStatsLine(parent->Res().intLabel, stats.Intelligence(), screen, position);
153
154         position += lineBreak;
155         RenderStatsLine(parent->Res().gutLabel, stats.Gut(), screen, position);
156
157         position += lineBreak;
158         RenderStatsLine(parent->Res().mgrLabel, stats.MagicResistance(), screen, position);
159 }
160
161 void StatusMenu::RenderStatsLine(const char *label, int number, SDL_Surface *screen, const Vector<int> &position) const {
162         const Font &font(*parent->Res().statusFont);
163         const Vector<int> numberOffset(4 * font.CharWidth(), 0);
164
165         font.DrawString(label, screen, position, 3);
166         font.DrawNumber(number, screen, position + numberOffset, 3);
167 }
168
169 void StatusMenu::RenderEquipment(SDL_Surface *screen, const Vector<int> &offset) const {
170         const Hero &hero(GetHero());
171         Vector<int> lineBreak(0, 2 * parent->Res().statusFont->CharHeight());
172
173         Vector<int> position(offset);
174         for (int i = 0; i < Hero::EQUIP_COUNT; ++i) {
175                 RenderEquipmentLine(hero.Equipment(Hero::EquipSlot(i)), screen, position);
176                 position += lineBreak;
177         }
178 }
179
180 void StatusMenu::RenderEquipmentLine(const Item *item, SDL_Surface *screen, const Vector<int> &position) const {
181         const Font &font(*parent->Res().statusFont);
182         const Vector<int> textOffset(font.CharWidth(), 0);
183         if (item) {
184                 if (item->MenuIcon()) {
185                         item->MenuIcon()->Draw(screen, position);
186                 }
187                 font.DrawString(item->Name(), screen, position + textOffset);
188         } else {
189                 font.DrawString(parent->Res().noEquipmentText, screen, position + textOffset);
190         }
191 }
192
193 void StatusMenu::RenderExperience(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
194         const Font &font(*parent->Res().statusFont);
195         font.DrawStringRight(parent->Res().experienceLabel, screen, offset, 10);
196
197         Vector<int> numberOffset(offset.X(), offset.Y() + font.CharHeight());
198         font.DrawNumberRight(GetHero().Experience(), screen, numberOffset, 7);
199 }
200
201 void StatusMenu::RenderNextLevel(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
202         const Font &font(*parent->Res().statusFont);
203         font.DrawStringRight(parent->Res().nextLevelLabel, screen, offset, 10);
204
205         Vector<int> numberOffset(offset.X(), offset.Y() + font.CharHeight());
206         font.DrawNumberRight(GetHero().NextLevel(), screen, numberOffset, 7);
207 }
208
209 void StatusMenu::RenderIkari(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
210         const Font &font(*parent->Res().statusFont);
211         font.DrawString(parent->Res().ipLabel, screen, offset, 5);
212
213         Vector<int> numberOffset(offset.X() + 5 * font.CharWidth(), offset.Y());
214         font.DrawNumber(GetHero().RelativeIP(100), screen, numberOffset, 3);
215
216         Vector<int> percentOffset(offset.X() + 8 * font.CharWidth(), offset.Y());
217         font.DrawChar('%', screen, percentOffset);
218 }
219
220 void StatusMenu::RenderMenu(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
221         const Font &font(*parent->Res().normalFont);
222         const Frame &frame(*parent->Res().statusFrame);
223
224         Vector<int> labelOffset(2 * font.CharWidth(), font.CharHeight());
225         frame.Draw(screen, offset, 10 * font.CharWidth(), 3 * font.CharHeight());
226         font.DrawString(parent->Res().mainMenuStatusText, screen, offset + labelOffset);
227
228         Vector<int> menuFrameOffset(10 * font.CharWidth(), 0);
229         Vector<int> menuOffset(13 * font.CharWidth(), font.CharHeight());
230         frame.Draw(screen, offset + menuFrameOffset, 20 * font.CharWidth(), 3 * font.CharHeight());
231         menu.Draw(screen, offset + menuOffset);
232 }
233
234
235 void StatusMenu::NextHero() {
236         cursor = (cursor + 1) % parent->Game().state->partySize;
237 }
238
239 void StatusMenu::PreviousHero() {
240         cursor = (cursor + parent->Game().state->partySize - 1) % parent->Game().state->partySize;
241 }
242
243 const Hero &StatusMenu::GetHero() const {
244         return *parent->Game().state->party[cursor];
245 }
246
247 }