-/*
- * EquipMenu.cpp
- *
- * Created on: Nov 18, 2012
- * Author: holy
- */
-
#include "EquipMenu.h"
#include "HeroStatus.h"
#include "../common/GameConfig.h"
#include "../common/GameState.h"
#include "../common/Hero.h"
+#include "../common/Inventory.h"
#include "../common/Item.h"
#include "../common/Stats.h"
#include "../graphics/Font.h"
using app::Input;
using common::Hero;
+using common::Inventory;
using common::Item;
using common::Stats;
using geometry::Vector;
void EquipMenu::OnEnterState(SDL_Surface *) {
equipmentMenu.SetInactive();
+ inventoryMenu.SetInactive();
}
void EquipMenu::OnExitState(SDL_Surface *) {
void EquipMenu::HandleEvents(const Input &input) {
-
+ if (input.JustPressed(Input::SHOULDER_LEFT)) {
+ PreviousHero();
+ }
+ if (input.JustPressed(Input::SHOULDER_RIGHT)) {
+ NextHero();
+ }
+ if (actionMenu.IsActive()) {
+ if (input.JustPressed(Input::PAD_UP)) {
+ actionMenu.PreviousRow();
+ }
+ if (input.JustPressed(Input::PAD_DOWN)) {
+ actionMenu.NextRow();
+ }
+ if (input.JustPressed(Input::ACTION_A)) {
+ switch (actionMenu.Selected()) {
+ case CHOICE_EQUIP:
+ LoadEquipment();
+ actionMenu.SetSelected();
+ equipmentMenu.SetActive();
+ break;
+ case CHOICE_STRONGEST:
+ // TODO: implement "equip strongest" when items' stat effects are done
+ break;
+ case CHOICE_REMOVE:
+ actionMenu.SetSelected();
+ equipmentMenu.SetActive();
+ break;
+ case CHOICE_REMOVE_ALL:
+ RemoveAllEquipment();
+ break;
+ case CHOICE_DROP:
+ actionMenu.SetSelected();
+ equipmentMenu.SetActive();
+ break;
+ }
+ } else if (input.JustPressed(Input::ACTION_B)) {
+ Ctrl().PopState();
+ }
+ } else if (equipmentMenu.IsActive()) {
+ if (input.JustPressed(Input::PAD_UP)) {
+ equipmentMenu.PreviousRow();
+ if (InventoryVisible()) {
+ LoadInventory();
+ }
+ }
+ if (input.JustPressed(Input::PAD_DOWN)) {
+ equipmentMenu.NextRow();
+ if (InventoryVisible()) {
+ LoadInventory();
+ }
+ }
+ if (input.JustPressed(Input::ACTION_B)) {
+ equipmentMenu.SetInactive();
+ actionMenu.SetActive();
+ } else if (input.JustPressed(Input::ACTION_A)) {
+ switch (actionMenu.Selected()) {
+ case CHOICE_EQUIP:
+ equipmentMenu.SetSelected();
+ inventoryMenu.SetActive();
+ break;
+ case CHOICE_STRONGEST:
+ case CHOICE_REMOVE_ALL:
+ // invalid state, recover
+ equipmentMenu.SetInactive();
+ actionMenu.SetActive();
+ break;
+ case CHOICE_REMOVE:
+ RemoveItem();
+ break;
+ case CHOICE_DROP:
+ DropItem();
+ break;
+ }
+ }
+ } else {
+ if (input.JustPressed(Input::PAD_UP)) {
+ inventoryMenu.PreviousRow();
+ }
+ if (input.JustPressed(Input::PAD_DOWN)) {
+ inventoryMenu.NextRow();
+ }
+ if (input.JustPressed(Input::ACTION_A)) {
+ EquipSelected();
+ inventoryMenu.SetInactive();
+ equipmentMenu.SetActive();
+ } else if (input.JustPressed(Input::ACTION_B)) {
+ inventoryMenu.SetInactive();
+ equipmentMenu.SetActive();
+ }
+ }
}
void EquipMenu::UpdateWorld(float deltaT) {
parent->Res().shoulderNav->Draw(screen, offset + shoulderNavOffset);
RenderStatus(screen, offset + parent->StatusOffset(0));
RenderStats(screen, offset + statsOffset);
- RenderEquipmentMenu(screen, equipOffset);
+ RenderEquipmentMenu(screen, offset + equipOffset);
+ if (InventoryVisible()) {
+ Vector<int> inventoryOffset(
+ parent->Res().statusFont->CharWidth(),
+ 17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
+ RenderInventoryMenu(screen, offset + inventoryOffset);
+ } else {
+ Vector<int> menuOffset(
+ 15 * parent->Res().statusFont->CharWidth(),
+ 17 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
+ RenderActionMenu(screen, offset + menuOffset);
+ }
}
int EquipMenu::Width() const {
}
void EquipMenu::RenderActionMenu(SDL_Surface *screen, const Vector<int> &offset) const {
+ const Font &font(*parent->Res().statusFont);
+ const Frame &frame(*parent->Res().statusFrame);
+ const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 2);
+ frame.Draw(screen, offset, 15 * font.CharWidth(), 10 * font.CharHeight());
+ actionMenu.Draw(screen, offset + menuOffset);
}
void EquipMenu::RenderInventoryMenu(SDL_Surface *screen, const Vector<int> &offset) const {
+ const Font &font(*parent->Res().normalFont);
+ const Frame &frame(*parent->Res().statusFrame);
+ const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 4);
+ frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
+ inventoryMenu.Draw(screen, offset + menuOffset);
}
void EquipMenu::NextHero() {
cursor = (cursor + 1) % parent->Game().state->partySize;
LoadEquipment();
+ if (InventoryVisible()) {
+ LoadInventory();
+ }
}
void EquipMenu::PreviousHero() {
cursor = (cursor + parent->Game().state->partySize - 1) % parent->Game().state->partySize;
LoadEquipment();
+ if (InventoryVisible()) {
+ LoadInventory();
+ }
+}
+
+Hero &EquipMenu::GetHero() {
+ return *parent->Game().state->party[cursor];
}
const Hero &EquipMenu::GetHero() const {
return *parent->Game().state->party[cursor];
}
+
void EquipMenu::LoadEquipment() {
equipmentMenu.Clear();
- equipmentMenu.Add(GetHero().Weapon()->Name(), GetHero().Weapon(), true, GetHero().Weapon()->MenuIcon());
- equipmentMenu.Add(GetHero().Armor()->Name(), GetHero().Armor(), true, GetHero().Armor()->MenuIcon());
- equipmentMenu.Add(GetHero().Shield()->Name(), GetHero().Shield(), true, GetHero().Shield()->MenuIcon());
- equipmentMenu.Add(GetHero().Helmet()->Name(), GetHero().Helmet(), true, GetHero().Helmet()->MenuIcon());
- equipmentMenu.Add(GetHero().Ring()->Name(), GetHero().Ring(), true, GetHero().Ring()->MenuIcon());
- equipmentMenu.Add(GetHero().Jewel()->Name(), GetHero().Jewel(), true, GetHero().Jewel()->MenuIcon());
+ for (int i = 0; i < Hero::EQUIP_COUNT; ++i) {
+ if (GetHero().Equipped(Hero::EquipSlot(i))) {
+ const Item *item(GetHero().Equipment(Hero::EquipSlot(i)));
+ equipmentMenu.Add(item->Name(), item, true, item->MenuIcon());
+ } else {
+ equipmentMenu.Add(parent->Res().noEquipmentText, 0);
+ }
+ }
+}
+
+void EquipMenu::RemoveAllEquipment() {
+ Inventory &inv(parent->Game().state->inventory);
+ for (int i = 0; i < Hero::EQUIP_COUNT; ++i) {
+ if (GetHero().Equipped(Hero::EquipSlot(i))
+ && inv.Add(GetHero().Equipment(Hero::EquipSlot(i)), 1)) {
+ GetHero().RemoveEquipment(Hero::EquipSlot(i));
+ }
+ }
+ LoadEquipment();
+}
+
+void EquipMenu::RemoveItem() {
+ Inventory &inv(parent->Game().state->inventory);
+ Hero::EquipSlot slot = Hero::EquipSlot(equipmentMenu.SelectedIndex());
+
+ if (GetHero().Equipped(slot) && inv.Add(GetHero().Equipment(slot), 1)) {
+ GetHero().RemoveEquipment(slot);
+ }
+
+ LoadEquipment();
+}
+
+void EquipMenu::DropItem() {
+ GetHero().RemoveEquipment(Hero::EquipSlot(equipmentMenu.SelectedIndex()));
+ LoadEquipment();
+}
+
+
+bool EquipMenu::InventoryVisible() const {
+ return !actionMenu.IsActive() && actionMenu.Selected() == CHOICE_EQUIP;
+}
+
+void EquipMenu::LoadInventory() {
+ const Inventory &inv = parent->Game().state->inventory;
+ const Hero &hero = GetHero();
+ const Hero::EquipSlot slot = Hero::EquipSlot(equipmentMenu.SelectedIndex());
+
+ inventoryMenu.Clear();
+ for (int i = 0; i < inv.MaxItems(); ++i) {
+ const Item *item = inv.ItemAt(i);
+ if (item && item->EquipableAt(slot)) {
+ inventoryMenu.Add(item->Name(), item, hero.CanEquip(*item),
+ item->MenuIcon(), inv.ItemCountAt(i));
+ }
+ }
+}
+
+void EquipMenu::EquipSelected() {
+ Inventory &inv = parent->Game().state->inventory;
+ Hero &hero = GetHero();
+ const Hero::EquipSlot slot = Hero::EquipSlot(equipmentMenu.SelectedIndex());
+
+ const Item *selected = inventoryMenu.Selected();
+ const Item *equipped = equipmentMenu.Selected();
+
+ if (!hero.CanEquip(*selected)) {
+ // TODO: error noise and blur
+ return;
+ }
+
+ inv.Remove(selected, 1);
+ if (!inv.Add(equipped, 1)) {
+ // roll back
+ inv.Add(selected, 1);
+ // TODO: error noise, blur, message?
+ return;
+ }
+
+ hero.SetEquipment(slot, selected);
+ LoadEquipment();
+ LoadInventory();
}
}