4 * Created on: Nov 18, 2012
10 #include "HeroStatus.h"
11 #include "PartyMenu.h"
12 #include "Resources.h"
13 #include "../app/Application.h"
14 #include "../app/Input.h"
15 #include "../common/GameConfig.h"
16 #include "../common/GameState.h"
17 #include "../common/Hero.h"
18 #include "../common/Inventory.h"
19 #include "../common/Item.h"
20 #include "../common/Stats.h"
21 #include "../graphics/Font.h"
22 #include "../graphics/Frame.h"
26 using common::Inventory;
29 using geometry::Vector;
31 using graphics::Frame;
35 EquipMenu::EquipMenu(PartyMenu *parent, int cursor)
38 , actionMenu(*parent->Res().equipmentActionMenuProperties)
39 , equipmentMenu(*parent->Res().equipmentMenuProperties)
40 , inventoryMenu(*parent->Res().inventoryMenuProperties) {
41 actionMenu.Add(parent->Res().equipMenuEquipLabel, CHOICE_EQUIP);
42 actionMenu.Add(parent->Res().equipMenuStrongestLabel, CHOICE_STRONGEST);
43 actionMenu.Add(parent->Res().equipMenuRemoveLabel, CHOICE_REMOVE);
44 actionMenu.Add(parent->Res().equipMenuRemoveAllLabel, CHOICE_REMOVE_ALL);
45 actionMenu.Add(parent->Res().equipMenuDropLabel, CHOICE_DROP);
51 void EquipMenu::OnEnterState(SDL_Surface *) {
52 equipmentMenu.SetInactive();
53 inventoryMenu.SetInactive();
56 void EquipMenu::OnExitState(SDL_Surface *) {
60 void EquipMenu::OnResumeState(SDL_Surface *) {
64 void EquipMenu::OnPauseState(SDL_Surface *) {
69 void EquipMenu::OnResize(int width, int height) {
74 void EquipMenu::HandleEvents(const Input &input) {
75 if (actionMenu.IsActive()) {
76 if (input.JustPressed(Input::PAD_UP)) {
77 actionMenu.PreviousRow();
79 if (input.JustPressed(Input::PAD_DOWN)) {
82 if (input.JustPressed(Input::ACTION_A)) {
83 switch (actionMenu.Selected()) {
86 actionMenu.SetSelected();
87 equipmentMenu.SetActive();
89 case CHOICE_STRONGEST:
93 actionMenu.SetSelected();
94 equipmentMenu.SetActive();
96 case CHOICE_REMOVE_ALL:
100 actionMenu.SetSelected();
101 equipmentMenu.SetActive();
104 } else if (input.JustPressed(Input::ACTION_B)) {
107 } else if (equipmentMenu.IsActive()) {
108 if (input.JustPressed(Input::PAD_UP)) {
109 equipmentMenu.PreviousRow();
110 if (InventoryVisible()) {
114 if (input.JustPressed(Input::PAD_DOWN)) {
115 equipmentMenu.NextRow();
116 if (InventoryVisible()) {
120 if (input.JustPressed(Input::ACTION_B)) {
121 equipmentMenu.SetInactive();
122 actionMenu.SetActive();
123 } else if (input.JustPressed(Input::ACTION_A)) {
124 switch (actionMenu.Selected()) {
126 equipmentMenu.SetSelected();
127 inventoryMenu.SetActive();
129 case CHOICE_STRONGEST:
130 case CHOICE_REMOVE_ALL:
131 // invalid state, recover
132 equipmentMenu.SetInactive();
133 actionMenu.SetActive();
144 if (input.JustPressed(Input::PAD_UP)) {
145 inventoryMenu.PreviousRow();
147 if (input.JustPressed(Input::PAD_DOWN)) {
148 inventoryMenu.NextRow();
150 if (input.JustPressed(Input::ACTION_A)) {
151 // TODO: equip selected item
152 } else if (input.JustPressed(Input::ACTION_B)) {
153 inventoryMenu.SetInactive();
154 equipmentMenu.SetActive();
159 void EquipMenu::UpdateWorld(float deltaT) {
163 void EquipMenu::Render(SDL_Surface *screen) {
164 Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
165 Vector<int> shoulderNavOffset(
166 5 * parent->Res().statusFont->CharWidth(),
167 parent->Res().statusFont->CharHeight());
168 Vector<int> statsOffset(
169 4 * parent->Res().statusFont->CharWidth(),
170 8 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
171 Vector<int> equipOffset(
172 17 * parent->Res().statusFont->CharWidth(),
173 4 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
175 parent->RenderBackground(screen);
176 parent->Res().shoulderNav->Draw(screen, offset + shoulderNavOffset);
177 RenderStatus(screen, offset + parent->StatusOffset(0));
178 RenderStats(screen, offset + statsOffset);
179 RenderEquipmentMenu(screen, offset + equipOffset);
180 if (InventoryVisible()) {
181 Vector<int> inventoryOffset(
182 parent->Res().statusFont->CharWidth(),
183 17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
184 RenderInventoryMenu(screen, offset + inventoryOffset);
186 Vector<int> menuOffset(
187 15 * parent->Res().statusFont->CharWidth(),
188 17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
189 RenderActionMenu(screen, offset + menuOffset);
193 int EquipMenu::Width() const {
194 return parent->Width();
197 int EquipMenu::Height() const {
198 return parent->Height();
201 void EquipMenu::RenderStatus(SDL_Surface *screen, const Vector<int> &offset) const {
202 parent->GetHeroStatus(cursor).Render(screen, offset);
205 void EquipMenu::RenderStats(SDL_Surface *screen, const Vector<int> &offset) const {
206 const Stats &stats(GetHero().GetStats());
207 Vector<int> lineBreak(0, parent->Res().statusFont->CharHeight());
209 Vector<int> position(offset);
210 RenderStatsLine(parent->Res().atpLabel, stats.Attack(), screen, position);
212 position += lineBreak;
213 RenderStatsLine(parent->Res().dfpLabel, stats.Defense(), screen, position);
215 position += lineBreak;
216 RenderStatsLine(parent->Res().strLabel, stats.Strength(), screen, position);
218 position += lineBreak;
219 RenderStatsLine(parent->Res().aglLabel, stats.Agility(), screen, position);
221 position += lineBreak;
222 RenderStatsLine(parent->Res().intLabel, stats.Intelligence(), screen, position);
224 position += lineBreak;
225 RenderStatsLine(parent->Res().gutLabel, stats.Gut(), screen, position);
227 position += lineBreak;
228 RenderStatsLine(parent->Res().mgrLabel, stats.MagicResistance(), screen, position);
231 void EquipMenu::RenderStatsLine(const char *label, int number, SDL_Surface *screen, const Vector<int> &position) const {
232 const Font &font(*parent->Res().statusFont);
233 const Vector<int> numberOffset(4 * font.CharWidth(), 0);
235 font.DrawString(label, screen, position, 3);
236 font.DrawNumber(number, screen, position + numberOffset, 3);
239 void EquipMenu::RenderEquipmentMenu(SDL_Surface *screen, const Vector<int> &offset) const {
240 equipmentMenu.Draw(screen, offset);
243 void EquipMenu::RenderActionMenu(SDL_Surface *screen, const Vector<int> &offset) const {
244 const Font &font(*parent->Res().statusFont);
245 const Frame &frame(*parent->Res().statusFrame);
246 const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 2);
248 frame.Draw(screen, offset, 15 * font.CharWidth(), 10 * font.CharHeight());
249 actionMenu.Draw(screen, offset + menuOffset);
252 void EquipMenu::RenderInventoryMenu(SDL_Surface *screen, const Vector<int> &offset) const {
253 const Font &font(*parent->Res().normalFont);
254 const Frame &frame(*parent->Res().statusFrame);
255 const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 4);
257 frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
258 inventoryMenu.Draw(screen, offset + menuOffset);
262 void EquipMenu::NextHero() {
263 cursor = (cursor + 1) % parent->Game().state->partySize;
267 void EquipMenu::PreviousHero() {
268 cursor = (cursor + parent->Game().state->partySize - 1) % parent->Game().state->partySize;
272 Hero &EquipMenu::GetHero() {
273 return *parent->Game().state->party[cursor];
276 const Hero &EquipMenu::GetHero() const {
277 return *parent->Game().state->party[cursor];
281 void EquipMenu::LoadEquipment() {
282 equipmentMenu.Clear();
283 for (int i = 0; i < Hero::EQUIP_COUNT; ++i) {
284 if (GetHero().Equipped(Hero::EquipSlot(i))) {
285 const Item *item(GetHero().Equipment(Hero::EquipSlot(i)));
286 equipmentMenu.Add(item->Name(), item, true, item->MenuIcon());
288 equipmentMenu.Add(parent->Res().noEquipmentText, 0, false);
293 void EquipMenu::RemoveAllEquipment() {
294 Inventory &inv(parent->Game().state->inventory);
295 for (int i = 0; i < Hero::EQUIP_COUNT; ++i) {
296 if (GetHero().Equipped(Hero::EquipSlot(i))
297 && inv.Add(GetHero().Equipment(Hero::EquipSlot(i)), 1)) {
298 GetHero().RemoveEquipment(Hero::EquipSlot(i));
304 void EquipMenu::RemoveItem() {
305 Inventory &inv(parent->Game().state->inventory);
306 Hero::EquipSlot slot = Hero::EquipSlot(equipmentMenu.SelectedIndex());
308 if (GetHero().Equipped(slot) && inv.Add(GetHero().Equipment(slot), 1)) {
309 GetHero().RemoveEquipment(slot);
315 void EquipMenu::DropItem() {
316 GetHero().RemoveEquipment(Hero::EquipSlot(equipmentMenu.SelectedIndex()));
321 bool EquipMenu::InventoryVisible() const {
322 return !actionMenu.IsActive() && actionMenu.Selected() == CHOICE_EQUIP;
325 void EquipMenu::LoadInventory() {
326 const Inventory &inv = parent->Game().state->inventory;
327 const Hero &hero = GetHero();
328 const Hero::EquipSlot slot = Hero::EquipSlot(equipmentMenu.SelectedIndex());
330 inventoryMenu.Clear();
331 for (int i = 0; i < inv.MaxItems(); ++i) {
332 const Item *item = inv.ItemAt(i);
333 if (item && item->EquipableAt(slot)) {
334 inventoryMenu.Add(item->Name(), item, hero.CanEquip(*item),
335 item->MenuIcon(), inv.ItemCountAt(i));