1 #include "StatusMenu.h"
3 #include "HeroStatus.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"
20 using geometry::Vector;
22 using graphics::Frame;
26 StatusMenu::StatusMenu(PartyMenu *parent, int cursor)
29 , menu(*parent->Res().statusMenuProperties) {
30 menu.Add(parent->Res().nextLabel, 0);
31 menu.Add(parent->Res().returnLabel, 1);
35 void StatusMenu::OnEnterState(SDL_Surface *) {
39 void StatusMenu::OnExitState(SDL_Surface *) {
43 void StatusMenu::OnResumeState(SDL_Surface *) {
47 void StatusMenu::OnPauseState(SDL_Surface *) {
52 void StatusMenu::OnResize(int width, int height) {
57 void StatusMenu::HandleEvents(const Input &input) {
58 if (input.JustPressed(Input::SHOULDER_RIGHT)) {
61 if (input.JustPressed(Input::SHOULDER_LEFT)) {
65 if (input.JustPressed(Input::PAD_LEFT)) {
68 if (input.JustPressed(Input::PAD_RIGHT)) {
72 if (input.JustPressed(Input::ACTION_A)) {
73 if (menu.Selected() == 0) {
75 } else if (menu.Selected() == 1) {
79 if (input.JustPressed(Input::ACTION_B)) {
84 void StatusMenu::UpdateWorld(float deltaT) {
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);
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);
123 int StatusMenu::Width() const {
124 return parent->Width();
127 int StatusMenu::Height() const {
128 return parent->Height();
131 void StatusMenu::RenderStatus(SDL_Surface *screen, const Vector<int> &offset) const {
132 parent->GetHeroStatus(cursor).Render(screen, offset);
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());
139 Vector<int> position(offset);
140 RenderStatsLine(parent->Res().atpLabel, stats.Attack(), screen, position);
142 position += lineBreak;
143 RenderStatsLine(parent->Res().dfpLabel, stats.Defense(), screen, position);
145 position += lineBreak;
146 RenderStatsLine(parent->Res().strLabel, stats.Strength(), screen, position);
148 position += lineBreak;
149 RenderStatsLine(parent->Res().aglLabel, stats.Agility(), screen, position);
151 position += lineBreak;
152 RenderStatsLine(parent->Res().intLabel, stats.Intelligence(), screen, position);
154 position += lineBreak;
155 RenderStatsLine(parent->Res().gutLabel, stats.Gut(), screen, position);
157 position += lineBreak;
158 RenderStatsLine(parent->Res().mgrLabel, stats.MagicResistance(), screen, position);
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);
165 font.DrawString(label, screen, position, 3);
166 font.DrawNumber(number, screen, position + numberOffset, 3);
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());
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;
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);
184 if (item->MenuIcon()) {
185 item->MenuIcon()->Draw(screen, position);
187 font.DrawString(item->Name(), screen, position + textOffset);
189 font.DrawString(parent->Res().noEquipmentText, screen, position + textOffset);
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);
197 Vector<int> numberOffset(offset.X(), offset.Y() + font.CharHeight());
198 font.DrawNumberRight(GetHero().Experience(), screen, numberOffset, 7);
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);
205 Vector<int> numberOffset(offset.X(), offset.Y() + font.CharHeight());
206 font.DrawNumberRight(GetHero().NextLevel(), screen, numberOffset, 7);
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);
213 Vector<int> numberOffset(offset.X() + 5 * font.CharWidth(), offset.Y());
214 font.DrawNumber(GetHero().RelativeIP(100), screen, numberOffset, 3);
216 Vector<int> percentOffset(offset.X() + 8 * font.CharWidth(), offset.Y());
217 font.DrawChar('%', screen, percentOffset);
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);
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);
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);
235 void StatusMenu::NextHero() {
236 cursor = (cursor + 1) % parent->Game().state->partySize;
239 void StatusMenu::PreviousHero() {
240 cursor = (cursor + parent->Game().state->partySize - 1) % parent->Game().state->partySize;
243 const Hero &StatusMenu::GetHero() const {
244 return *parent->Game().state->party[cursor];