#include "states/SelectMoveAction.h"
#include "../app/Application.h"
#include "../app/Input.h"
+#include "../common/Ikari.h"
#include "../common/Inventory.h"
#include "../common/Item.h"
#include "../common/Spell.h"
spellMenus.push_back(res->spellMenuPrototype);
LoadSpellMenu(i);
ikariMenus.push_back(res->ikariMenuPrototype);
- // TODO: insert ikari menu entries
+ LoadIkariMenu(i);
heroTags[i] = HeroTag(&heroes[i], attackChoices + i, res, HeroTag::Alignment((i + 1) % 2));
}
}
}
+void BattleState::LoadIkariMenu(vector<Hero>::size_type index) {
+ ikariMenus[index].Clear();
+ ikariMenus[index].Reserve(6);
+
+ if (HeroAt(index).HasWeapon()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Weapon()->Name(),
+ HeroAt(index).Weapon(),
+ HeroAt(index).Weapon()->HasIkari() && HeroAt(index).Weapon()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->weaponMenuIcon,
+ 0,
+ HeroAt(index).Weapon()->HasIkari() ? HeroAt(index).Weapon()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->weaponMenuIcon);
+ }
+
+ if (HeroAt(index).HasArmor()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Armor()->Name(),
+ HeroAt(index).Armor(),
+ HeroAt(index).Armor()->HasIkari() && HeroAt(index).Armor()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->armorMenuIcon,
+ 0,
+ HeroAt(index).Armor()->HasIkari() ? HeroAt(index).Armor()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->armorMenuIcon);
+ }
+
+ if (HeroAt(index).HasShield()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Shield()->Name(),
+ HeroAt(index).Shield(),
+ HeroAt(index).Shield()->HasIkari() && HeroAt(index).Shield()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->shieldMenuIcon,
+ 0,
+ HeroAt(index).Shield()->HasIkari() ? HeroAt(index).Shield()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->shieldMenuIcon);
+ }
+
+ if (HeroAt(index).HasHelmet()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Helmet()->Name(),
+ HeroAt(index).Helmet(),
+ HeroAt(index).Helmet()->HasIkari() && HeroAt(index).Helmet()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->helmetMenuIcon,
+ 0,
+ HeroAt(index).Helmet()->HasIkari() ? HeroAt(index).Helmet()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->helmetMenuIcon);
+ }
+
+ if (HeroAt(index).HasRing()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Ring()->Name(),
+ HeroAt(index).Ring(),
+ HeroAt(index).Ring()->HasIkari() && HeroAt(index).Ring()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->ringMenuIcon,
+ 0,
+ HeroAt(index).Ring()->HasIkari() ? HeroAt(index).Ring()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->ringMenuIcon);
+ }
+
+ if (HeroAt(index).HasJewel()) {
+ ikariMenus[index].Add(
+ HeroAt(index).Jewel()->Name(),
+ HeroAt(index).Jewel(),
+ HeroAt(index).Jewel()->HasIkari() && HeroAt(index).Jewel()->GetIkari()->Cost() <= HeroAt(index).IP(),
+ res->jewelMenuIcon,
+ 0,
+ HeroAt(index).Jewel()->HasIkari() ? HeroAt(index).Jewel()->GetIkari()->Name() : "");
+ } else {
+ ikariMenus[index].Add(res->noEquipmentText, 0, false, res->jewelMenuIcon);
+ }
+}
+
void BattleState::LoadInventory() {
const Inventory &inv(*res->inventory);
itemMenu.Clear();
public:
Menu();
- Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap = 0, int iconSpace = 0, int cols = 1, int colGap = 0, int charsPerNumber = 0, char delimiter = ':');
+ Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap = 0, int iconSpace = 0, int cols = 1, int colGap = 0, int charsPerNumber = 0, char delimiter = ':', int charsPerAdditionalText = 0, int additionalTextGap = 0);
public:
int Width() const;
int Height() const;
- int ColWidth() const { return iconSpace + font->CharWidth() * (charsPerEntry + charsPerNumber) + (charsPerNumber ? font->CharWidth() : 0); }
+ int ColWidth() const;
int RowHeight() const { return font->CharHeight() + rowGap; }
int CharsPerEntry() const { return charsPerEntry; }
T &ValueAt(int index) { return entries[index].value; }
const T &ValueAt(int index) const { return entries[index].value; }
- void Add(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0, int number = 0) { entries.push_back(Entry(title, value, enabled, icon, number)); }
+ void Add(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0, int number = 0, const char *additionalText = 0) { entries.push_back(Entry(title, value, enabled, icon, number, additionalText)); }
void AddEmptyEntry() { entries.push_back(Entry(0, T(), false)); }
void Disable(int index) { entries[index].enabled = false; }
void Enable(int index) { entries[index].enabled = true; }
private:
struct Entry {
- Entry(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0, int number = 0)
- : title(title), icon(icon), number(number), value(value), enabled(enabled) { }
+ Entry(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0, int number = 0, const char *additionalText = 0)
+ : title(title), additionalText(additionalText), icon(icon), number(number), value(value), enabled(enabled) { }
const char *title;
+ const char *additionalText;
const Sprite *icon;
int number;
T value;
int selected;
int topRow;
int charsPerNumber;
+ int charsPerAdditionalText;
+ int additionalTextGap;
char delimiter;
};
, selected(0)
, topRow(0)
, charsPerNumber(0)
+, charsPerAdditionalText(0)
+, additionalTextGap(0)
, delimiter(':') {
}
template<class T>
-Menu<T>::Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap, int iconSpace, int cols, int colGap, int charsPerNumber, char delimiter)
+Menu<T>::Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap, int iconSpace, int cols, int colGap, int charsPerNumber, char delimiter, int charsPerAdditionalText, int additionalTextGap)
: font(font)
, disabledFont(disabledFont ? disabledFont : font)
, cursor(cursor)
, selected(0)
, topRow(0)
, charsPerNumber(charsPerNumber)
+, charsPerAdditionalText(charsPerAdditionalText)
+, additionalTextGap(additionalTextGap)
, delimiter(delimiter) {
}
+template<class T>
+int Menu<T>::ColWidth() const {
+ int width(iconSpace);
+ width += font->CharWidth() * (charsPerEntry + charsPerNumber);
+ if (charsPerNumber) {
+ width += font->CharWidth();
+ }
+ if (charsPerAdditionalText) {
+ width += additionalTextGap + charsPerAdditionalText * font->CharWidth();
+ }
+ return width;
+}
+
template<class T>
int Menu<T>::Width() const {
return cols * ColWidth() + (cols - 1) * colGap;
if (entries[start + i].icon) {
entries[start + i].icon->Draw(dest, position + iconOffset);
}
- geometry::Vector<int> labelOffset(iconOffset.X() + iconSpace, iconOffset.Y());
+ geometry::Vector<int> textOffset(iconOffset.X() + iconSpace, iconOffset.Y());
const Font *usedFont(entries[start + i].enabled ? font : disabledFont);
- usedFont->DrawString(entries[start + i].title, dest, position + labelOffset, charsPerEntry);
+ usedFont->DrawString(entries[start + i].title, dest, position + textOffset, charsPerEntry);
+
+ textOffset += geometry::Vector<int>(charsPerEntry * usedFont->CharWidth(), 0);
+
+ if (charsPerAdditionalText) {
+ textOffset += geometry::Vector<int>(additionalTextGap, 0);
+ if (entries[start + i].additionalText) {
+ usedFont->DrawString(entries[start + i].additionalText, dest, position + textOffset, charsPerAdditionalText);
+ }
+ textOffset += geometry::Vector<int>(charsPerAdditionalText * usedFont->CharWidth(), 0);
+ }
if (charsPerNumber) {
- geometry::Vector<int> delimiterOffset(labelOffset.X() + charsPerEntry * usedFont->CharWidth(), labelOffset.Y());
- usedFont->DrawChar(delimiter, dest, position + delimiterOffset);
- geometry::Vector<int> numberOffset(delimiterOffset.X() + usedFont->CharWidth(), delimiterOffset.Y());
- usedFont->DrawNumber(entries[start + i].number, dest, position + numberOffset);
+ usedFont->DrawChar(delimiter, dest, position + textOffset);
+ textOffset += geometry::Vector<int>(usedFont->CharWidth(), 0);
+ usedFont->DrawNumber(entries[start + i].number, dest, position + textOffset);
}
}
geometry::Vector<int> cursorOffset(
maxim.SetHealth(33);
maxim.SetMaxMana(20);
maxim.SetMana(20);
- maxim.SetIP(100);
+ maxim.SetIP(55);
SDL_Surface *selanImg(IMG_Load("test-data/selan.png"));
Sprite selanSprite(selanImg, 64, 64);
battleRes.ikariMenuHeadline = "Please choose equipment.";
battleRes.noEquipmentText = "No equip";
- battleRes.ikariMenuPrototype = Menu<const Item *>(&normalFont, &disabledFont, &handCursorSprite, 26, 6, 8, 16, 1, 32);
- battleRes.ikariMenuPrototype.Add("Zirco whip Thundershriek", 0, false, &swordIcon);
- battleRes.ikariMenuPrototype.Add("Zircon plate Sudden cure", 0, true, &armorIcon);
- battleRes.ikariMenuPrototype.Add("Zirco gloves Forcefield", 0, true, &shieldIcon);
- battleRes.ikariMenuPrototype.Add("Holy cap Vulnerable", 0, false, &helmetIcon);
- battleRes.ikariMenuPrototype.Add("Ghost ring Destroy", 0, true, &ringIcon);
- battleRes.ikariMenuPrototype.Add("Eagle rock Dive", 0, true, &jewelIcon);
+ battleRes.ikariMenuPrototype = Menu<const Item *>(&normalFont, &disabledFont, &handCursorSprite, 12, 6, normalFont.CharHeight() / 2, normalFont.CharWidth(), 1, normalFont.CharWidth() * 2, 0, ':', 12, normalFont.CharWidth());
BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &battleRes));
battleState->AddMonster(monster);