# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
../src/common/Inventory.cpp \
-../src/common/Item.cpp
+../src/common/Item.cpp \
+../src/common/Spell.cpp
OBJS += \
./src/common/Inventory.o \
-./src/common/Item.o
+./src/common/Item.o \
+./src/common/Spell.o
CPP_DEPS += \
./src/common/Inventory.d \
-./src/common/Item.d
+./src/common/Item.d \
+./src/common/Spell.d
# Each subdirectory must supply rules for building sources it contributes
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
../src/common/Inventory.cpp \
-../src/common/Item.cpp
+../src/common/Item.cpp \
+../src/common/Spell.cpp
OBJS += \
./src/common/Inventory.o \
-./src/common/Item.o
+./src/common/Item.o \
+./src/common/Spell.o
CPP_DEPS += \
./src/common/Inventory.d \
-./src/common/Item.d
+./src/common/Item.d \
+./src/common/Spell.d
# Each subdirectory must supply rules for building sources it contributes
#include "../app/Input.h"
#include "../common/Inventory.h"
#include "../common/Item.h"
+#include "../common/Spell.h"
#include "../geometry/operators.h"
#include "../graphics/Sprite.h"
using app::Input;
using common::Inventory;
using common::Item;
+using common::Spell;
using geometry::Point;
using geometry::Vector;
using graphics::Menu;
heroesLayout->CalculatePositions(background->w, background->h, heroesPositions);
for (vector<Hero>::size_type i(0), end(heroes.size()); i < end; ++i) {
spellMenus.push_back(res->spellMenuPrototype);
- // TODO: insert spell menu entries
+ LoadSpellMenu(i);
ikariMenus.push_back(res->ikariMenuPrototype);
// TODO: insert ikari menu entries
heroTags[i] = HeroTag(&heroes[i], attackChoices + i, res, HeroTag::Alignment((i + 1) % 2));
LoadInventory();
}
+void BattleState::LoadSpellMenu(vector<Hero>::size_type index) {
+ spellMenus[index].Clear();
+ spellMenus[index].Reserve(HeroAt(index).Spells().size());
+ for (vector<const Spell *>::const_iterator i(HeroAt(index).Spells().begin()), end(HeroAt(index).Spells().end()); i != end; ++i) {
+ bool enabled((*i)->CanUseInBattle() && (*i)->Cost() <= HeroAt(index).Mana());
+ spellMenus[index].Add((*i)->Name(), *i, enabled, 0, (*i)->Cost());
+ }
+}
+
void BattleState::LoadInventory() {
const Inventory &inv(*res->inventory);
itemMenu.Clear();
namespace common {
class Inventory;
class Item;
+ class Spell;
}
namespace graphics {
class Font;
const TargetSelection &ActiveHeroTargets() const { return attackChoices[activeHero].Selection(); }
bool AttackSelectionDone() const { return activeHero >= (int) heroes.size(); }
- graphics::Menu</* Spell */ void *> &GetSpellMenu() { return spellMenus[activeHero]; }
- const graphics::Menu</* Spell */ void *> &GetSpellMenu() const { return spellMenus[activeHero]; }
+ graphics::Menu<const common::Spell *> &GetSpellMenu() { return spellMenus[activeHero]; }
+ const graphics::Menu<const common::Spell *> &GetSpellMenu() const { return spellMenus[activeHero]; }
graphics::Menu</* Ikari or Item */ void *> &GetIkariMenu() { return ikariMenus[activeHero]; }
const graphics::Menu</* Ikari or Item */ void *> &GetIkariMenu() const { return ikariMenus[activeHero]; }
graphics::Menu<const common::Item *> &GetItemMenu() { return itemMenu; }
void RenderHeroTags(SDL_Surface *screen, const geometry::Vector<int> &offset);
private:
+ void LoadSpellMenu(std::vector<Hero>::size_type heroIndex);
void LoadInventory();
private:
std::vector<geometry::Point<int> > heroesPositions;
std::vector<Monster> monsters;
std::vector<Hero> heroes;
- std::vector<graphics::Menu</* Spell */ void *> > spellMenus;
+ std::vector<graphics::Menu<const common::Spell *> > spellMenus;
graphics::Menu<const common::Item *> itemMenu;
std::vector<graphics::Menu</* Ikari or Item */ void *> > ikariMenus;
HeroTag heroTags[4];
#ifndef BATTLE_HERO_H_
#define BATTLE_HERO_H_
+#include <vector>
#include <SDL.h>
+namespace common { class Spell; }
namespace graphics { class Sprite; }
namespace battle {
Uint8 Level() const { return level; }
const graphics::Sprite *Sprite() const { return sprite; }
+ const std::vector<const common::Spell *> &Spells() const { return spells; }
+
Uint16 MaxHealth() const { return maxHealth; }
Uint16 Health() const { return health; }
int RelativeHealth(int max) const { return health * max / maxHealth; }
void SetMana(Uint16 m) { mana = m; }
void SetIP(Uint8 i) { ip = i; }
+ void AddSpell(const common::Spell *s) { spells.push_back(s); }
+
private:
const char *name;
graphics::Sprite *sprite;
- // TODO: equipment and spells lists
+
+ // TODO: vector does not seem to be a good choice
+ std::vector<const common::Spell *> spells;
+ // TODO: equipment list
Uint16 maxHealth, health;
Uint16 maxMana, mana;
namespace common {
class Inventory;
class Item;
+ class Spell;
}
namespace graphics {
class Font;
graphics::Sprite *itemTargetCursor;
const char *spellMenuHeadline;
- graphics::Menu</* Spell */ void *> spellMenuPrototype;
+ graphics::Menu<const common::Spell *> spellMenuPrototype;
common::Inventory *inventory;
const char *itemMenuHeadline;
if (battle->GetItemMenu().SelectedIsEnabled()) {
const Item *item(battle->GetItemMenu().Selected());
battle->ActiveHeroTargets().Reset();
- if (item->TargetAlly()) {
+ if (item->GetTargetingMode().TargetsAlly()) {
battle->ActiveHeroTargets().SelectHeroes();
} else {
battle->ActiveHeroTargets().SelectEnemies();
}
- if (item->TargetAll()) {
+ if (item->GetTargetingMode().TargetsAll()) {
battle->SetAttackType(AttackChoice::ITEM);
// TODO: remove item from inventory
battle->ActiveHeroAttackChoice().SetItem(item);
battle->NextHero();
ctrl->PopState();
} else {
- if (item->TargetOne()) {
+ if (item->GetTargetingMode().TargetsSingle()) {
battle->ActiveHeroTargets().SetSingle();
} else {
battle->ActiveHeroTargets().SetMultiple();
--- /dev/null
+/*
+ * HeroGroup.h
+ *
+ * Created on: Aug 10, 2012
+ * Author: holy
+ */
+
+#ifndef COMMON_HEROGROUP_H_
+#define COMMON_HEROGROUP_H_
+
+#include <SDL.h>
+
+namespace common {
+
+class HeroGroup {
+
+public:
+ HeroGroup() : members(NOBODY) { }
+
+public:
+ bool HasMaxim() const { return members & MAXIM; }
+ bool HasSelan() const { return members & SELAN; }
+ bool HasGuy() const { return members & GUY; }
+ bool HasArtea() const { return members & ARTEA; }
+ bool HasTia() const { return members & TIA; }
+ bool HasDekar() const { return members & DEKAR; }
+ bool HasLexis() const { return members & LEXIS; }
+
+ void AddMaxim() { members |= MAXIM; }
+ void AddSelan() { members |= SELAN; }
+ void AddGuy() { members |= GUY; }
+ void AddArtea() { members |= ARTEA; }
+ void AddTia() { members |= TIA; }
+ void AddDekar() { members |= DEKAR; }
+ void AddLexis() { members |= LEXIS; }
+ void AddAll() { members = (MAXIM | SELAN | GUY | ARTEA | TIA | DEKAR | LEXIS); }
+
+ void RemoveMaxim() { members &= ~MAXIM; }
+ void RemoveSelan() { members &= ~SELAN; }
+ void RemoveGuy() { members &= ~GUY; }
+ void RemoveArtea() { members &= ~ARTEA; }
+ void RemoveTia() { members &= ~TIA; }
+ void RemoveDekar() { members &= ~DEKAR; }
+ void RemoveLexis() { members &= ~LEXIS; }
+ void RemoveAll() { members = NOBODY; }
+
+public:
+ enum {
+ NOBODY = 0,
+ MAXIM = 1,
+ SELAN = 2,
+ GUY = 4,
+ ARTEA = 8,
+ TIA = 16,
+ DEKAR = 32,
+ LEXIS = 64,
+ };
+ Uint8 members;
+
+};
+
+}
+
+#endif /* COMMON_HEROGROUP_H_ */
namespace common {
Item::Item()
-: menuIcon(0)
+: name("")
+, menuIcon(0)
, chestIcon(0)
, value(0)
, properties(0)
, usability(0)
-, targettingMode(0)
-, equipable(0)
-, equipableBy(0) {
+, equipable(0) {
}
#ifndef COMMON_ITEM_H_
#define COMMON_ITEM_H_
+#include "HeroGroup.h"
+#include "TargetingMode.h"
+
#include <SDL.h>
namespace graphics { class Sprite; }
bool CanUseOnStatusScreen() const { return usability & USABILITY_STATUS; }
bool CanUseInBattle() const { return usability & USABILITY_BATTLE; }
- bool TargetEnemy() const { return targettingMode & TARGETTING_MODE_ENEMY; }
- bool TargetAlly() const { return !TargetEnemy(); }
- bool TargetAll() const { return (targettingMode & TARGETTING_MODE_COUNT_MASK) == TARGETTING_MODE_ALL; }
- bool TargetMultiple() const { return (targettingMode & TARGETTING_MODE_COUNT_MASK) == TARGETTING_MODE_MULTIPLE; }
- bool TargetOne() const { return (targettingMode & TARGETTING_MODE_COUNT_MASK) == TARGETTING_MODE_ONE; }
+ TargetingMode &GetTargetingMode() { return targettingMode; }
+ const TargetingMode &GetTargetingMode() const { return targettingMode; }
bool HasMenuIcon() const { return menuIcon; }
const graphics::Sprite *MenuIcon() const { return menuIcon; }
bool CanEquipRing() const { return equipable & EQUIPPABLE_RING; }
bool CanEquipJewel() const { return equipable & EQUIPPABLE_JEWEL; }
- bool EquipableByMaxim() const { return equipableBy & EQUIPABLE_BY_MAXIM; }
- bool EquipableBySelan() const { return equipableBy & EQUIPABLE_BY_SELAN; }
- bool EquipableByGuy() const { return equipableBy & EQUIPABLE_BY_GUY; }
- bool EquipableByArtea() const { return equipableBy & EQUIPABLE_BY_ARTEA; }
- bool EquipableByTia() const { return equipableBy & EQUIPABLE_BY_TIA; }
- bool EquipableByDekar() const { return equipableBy & EQUIPABLE_BY_DEKAR; }
- bool EquipableByLexis() const { return equipableBy & EQUIPABLE_BY_LEXIS; }
+ HeroGroup &EquipableBy() { return equipableBy; }
+ const HeroGroup &EquipableBy() const { return equipableBy; }
- bool HasItemEffectOnStatusScreen() const { return properties & PROPERTY_HAS_ITEM_EFFECT_STATUS; }
- bool HasItemEffectInBattle() const { return properties & PROPERTY_HAS_ITEM_EFFECT_BATTLE; }
+ bool HasEffectOnStatusScreen() const { return properties & PROPERTY_HAS_EFFECT_STATUS; }
+ bool HasEffectInBattle() const { return properties & PROPERTY_HAS_EFFECT_BATTLE; }
bool HasWeaponEffect() const { return properties & PROPERTY_HAS_WEAPON_EFFECT; }
bool HasArmorEffect() const { return properties & PROPERTY_HAS_ARMOR_EFFECT; }
bool IncreasesATP() const { return properties & PROPERTY_INCREASE_ATP; }
void SetName(const char *n) { name = n; }
void SetMenuIcon(const graphics::Sprite *icon) { menuIcon = icon; }
void SetUsableInBattle() { usability |= USABILITY_BATTLE; }
- void SetTargettingMode(int m) { targettingMode = m; }
-public:
+private:
enum Usability {
USABILITY_MOST_USEFUL = 1,
USABILITY_EQUIPABLE = 2,
USABILITY_STATUS = 64,
USABILITY_BATTLE = 128,
};
- enum TargettingMode {
- TARGETTING_MODE_ALL = 0,
- TARGETTING_MODE_ALLY = 0,
- TARGETTING_MODE_MULTIPLE = 1,
- TARGETTING_MODE_ONE = 2,
- TARGETTING_MODE_COUNT_MASK = 127,
- TARGETTING_MODE_ENEMY = 128,
- TARGETTING_MODE_FACTION_MASK = 128,
- };
enum Equipable {
EQUIPPABLE_NONE = 0,
EQUIPPABLE_WEAPON = 1,
EQUIPPABLE_RING = 16,
EQUIPPABLE_JEWEL = 32,
};
- enum EquipableBy {
- EQUIPABLE_BY_NOBODY = 0,
- EQUIPABLE_BY_MAXIM = 1,
- EQUIPABLE_BY_SELAN = 2,
- EQUIPABLE_BY_GUY = 4,
- EQUIPABLE_BY_ARTEA = 8,
- EQUIPABLE_BY_TIA = 16,
- EQUIPABLE_BY_DEKAR = 32,
- EQUIPABLE_BY_LEXIS = 64,
- };
enum Property {
- PROPERTY_HAS_ITEM_EFFECT_STATUS = 1,
- PROPERTY_HAS_ITEM_EFFECT_BATTLE = 2,
+ PROPERTY_HAS_EFFECT_STATUS = 1,
+ PROPERTY_HAS_EFFECT_BATTLE = 2,
PROPERTY_HAS_WEAPON_EFFECT = 4,
PROPERTY_HAS_ARMOR_EFFECT = 8,
PROPERTY_INCREASE_ATP = 16,
Uint16 properties;
Uint8 usability;
- Uint8 targettingMode;
+ TargetingMode targettingMode;
Uint8 equipable;
- Uint8 equipableBy;
+ HeroGroup equipableBy;
};
--- /dev/null
+/*
+ * Spell.cpp
+ *
+ * Created on: Aug 10, 2012
+ * Author: holy
+ */
+
+#include "Spell.h"
+
+namespace common {
+
+Spell::Spell()
+: name(""), value(0), cost(0), usability(0) {
+
+}
+
+}
--- /dev/null
+/*
+ * Spell.h
+ *
+ * Created on: Aug 10, 2012
+ * Author: holy
+ */
+
+#ifndef COMMON_SPELL_H_
+#define COMMON_SPELL_H_
+
+#include "HeroGroup.h"
+#include "TargetingMode.h"
+
+namespace common {
+
+class Spell {
+
+public:
+ Spell();
+
+public:
+ const char *Name() const { return name; }
+ Uint16 Value() const { return value; }
+ Uint8 Cost() const { return cost; }
+
+ bool CanUseOnStatusScreen() const { return usability & USABILITY_STATUS; }
+ bool CanUseInBattle() const { return usability & USABILITY_BATTLE; }
+
+ TargetingMode &GetTargetingMode() { return targetingMode; }
+ const TargetingMode &GetTargetingMode() const { return targetingMode; }
+
+ HeroGroup &UsableBy() { return usableBy; }
+ const HeroGroup &UsableBy() const { return usableBy; }
+
+ // TODO: add missing spell properties
+
+// temporary setters
+public:
+ void SetName(const char *n) { name = n; }
+ void SetCost(Uint8 c) { cost = c; }
+ void SetUsableInBattle() { usability |= USABILITY_BATTLE; }
+
+private:
+ enum Usability {
+ // USABILITY_UNUSED = 1,
+ // USABILITY_UNUSED = 2,
+ // USABILITY_UNUSED = 4,
+ // USABILITY_UNUSED = 8,
+ // USABILITY_UNUSED = 16,
+ // USABILITY_UNUSED = 32,
+ USABILITY_STATUS = 64,
+ USABILITY_BATTLE = 128,
+ };
+
+private:
+ const char *name;
+
+ Uint16 value;
+
+ Uint8 cost;
+ Uint8 usability;
+ TargetingMode targetingMode;
+ HeroGroup usableBy;
+
+};
+
+}
+
+#endif /* COMMON_SPELL_H_ */
--- /dev/null
+/*
+ * TargetingMode.h
+ *
+ * Created on: Aug 10, 2012
+ * Author: holy
+ */
+
+#ifndef COMMON_TARGETINGMODE_H_
+#define COMMON_TARGETINGMODE_H_
+
+#include <SDL.h>
+
+namespace common {
+
+class TargetingMode {
+
+public:
+ TargetingMode() : mode(0) { }
+
+public:
+ bool TargetsEnemy() const { return (mode & FACTION_MASK) == ENEMY; }
+ bool TargetsAlly() const { return (mode & FACTION_MASK) == ALLY; }
+ bool TargetsAll() const { return (mode & COUNT_MASK) == ALL; }
+ bool TargetsMultiple() const { return (mode & COUNT_MASK) == MULTIPLE; }
+ bool TargetsSingle() const { return (mode & COUNT_MASK) == SINGLE; }
+
+ void TargetAllEnemies() { mode = ENEMY | ALL; }
+ void TargetMultipleEnemies() { mode = ENEMY | MULTIPLE; }
+ void TargetSingleEnemy() { mode = ENEMY | SINGLE; }
+ void TargetAllAllies() { mode = ALLY | ALL; }
+ void TargetMultipleAllies() { mode = ALLY | MULTIPLE; }
+ void TargetSingleAlly() { mode = ALLY | SINGLE; }
+
+private:
+ enum {
+ ALL = 0,
+ ALLY = 0,
+ MULTIPLE = 1,
+ SINGLE = 2,
+ COUNT_MASK = 127,
+ ENEMY = 128,
+ FACTION_MASK = 128,
+ };
+ Uint8 mode;
+
+};
+
+}
+
+#endif /* COMMON_TARGETINGMODE_H_ */
#include "battle/Resources.h"
#include "common/Inventory.h"
#include "common/Item.h"
+#include "common/Spell.h"
#include "geometry/Point.h"
#include "graphics/Font.h"
#include "graphics/Frame.h"
using battle::PartyLayout;
using common::Inventory;
using common::Item;
+using common::Spell;
using geometry::Point;
using graphics::Font;
using graphics::Frame;
// TODO: add image for item targeting cursor
battleRes.itemTargetCursor = &itemTargetCursor;
+ Spell resetSpell;
+ resetSpell.SetName("Reset");
+ maxim.AddSpell(&resetSpell);
+ Spell strongSpell;
+ strongSpell.SetName("Strong");
+ strongSpell.SetCost(3);
+ strongSpell.SetUsableInBattle();
+ maxim.AddSpell(&strongSpell);
+ selan.AddSpell(&strongSpell);
+ Spell strongerSpell;
+ strongerSpell.SetName("Stronger");
+ strongerSpell.SetCost(8);
+ strongerSpell.SetUsableInBattle();
+ maxim.AddSpell(&strongerSpell);
+ selan.AddSpell(&strongerSpell);
+ Spell championSpell;
+ championSpell.SetName("Champion");
+ championSpell.SetCost(16);
+ championSpell.SetUsableInBattle();
+ maxim.AddSpell(&championSpell);
+ selan.AddSpell(&championSpell);
+ Spell rallySpell;
+ rallySpell.SetName("Rally");
+ rallySpell.SetCost(10);
+ rallySpell.SetUsableInBattle();
+ maxim.AddSpell(&rallySpell);
+ selan.AddSpell(&rallySpell);
+ Spell escapeSpell;
+ escapeSpell.SetName("Escape");
+ escapeSpell.SetCost(8);
+ selan.AddSpell(&escapeSpell);
+ Spell valorSpell;
+ valorSpell.SetName("Valor");
+ valorSpell.SetCost(30);
+ valorSpell.SetUsableInBattle();
+ maxim.AddSpell(&valorSpell);
+ selan.AddSpell(&valorSpell);
+
battleRes.spellMenuHeadline = "Please choose a spell.";
- battleRes.spellMenuPrototype = Menu</* Spell */ void *>(&normalFont, &disabledFont, &handCursorSprite, 12, 6, 8, 0, 2, 32);
- battleRes.spellMenuPrototype.Add("Reset : 0", 0, false);
- battleRes.spellMenuPrototype.Add("Strong : 3", 0);
- battleRes.spellMenuPrototype.Add("Stronger : 8", 0);
- battleRes.spellMenuPrototype.Add("Champion :16", 0);
- battleRes.spellMenuPrototype.Add("Rally :10", 0);
- battleRes.spellMenuPrototype.Add("Escape : 8", 0, false);
- battleRes.spellMenuPrototype.Add("Valor :30", 0);
+ battleRes.spellMenuPrototype = Menu<const Spell *>(&normalFont, &disabledFont, &handCursorSprite, 9, 6, 8, 0, 2, 32, 2, ':');
battleRes.spellMenuPrototype.Add("Poison : 2", 0);
battleRes.spellMenuPrototype.Add("Warp : 8", 0, false);
battleRes.spellMenuPrototype.Add("Release : 2", 0);
antidote.SetName("Antidote");
antidote.SetMenuIcon(&potionIcon);
antidote.SetUsableInBattle();
- antidote.SetTargettingMode(Item::TARGETTING_MODE_ALLY | Item::TARGETTING_MODE_ONE);
+ antidote.GetTargetingMode().TargetSingleAlly();
inventory.Add(&antidote, 9);
Item magicJar;
magicJar.SetName("Magic jar");
magicJar.SetMenuIcon(&potionIcon);
magicJar.SetUsableInBattle();
- magicJar.SetTargettingMode(Item::TARGETTING_MODE_ALLY | Item::TARGETTING_MODE_ONE);
+ antidote.GetTargetingMode().TargetSingleAlly();
inventory.Add(&magicJar, 4);
Item hiPotion;
hiPotion.SetName("Hi-Potion");
hiPotion.SetMenuIcon(&potionIcon);
hiPotion.SetUsableInBattle();
- hiPotion.SetTargettingMode(Item::TARGETTING_MODE_ALLY | Item::TARGETTING_MODE_ONE);
+ antidote.GetTargetingMode().TargetSingleAlly();
inventory.Add(&hiPotion, 4);
Item powerPotion;
powerPotion.SetName("Power potion");
sleepBall.SetName("Sleep ball");
sleepBall.SetMenuIcon(&ballIcon);
sleepBall.SetUsableInBattle();
- sleepBall.SetTargettingMode(Item::TARGETTING_MODE_ENEMY | Item::TARGETTING_MODE_ONE);
+ antidote.GetTargetingMode().TargetSingleEnemy();
inventory.Add(&sleepBall, 1);
Item multiBall;
multiBall.SetName("Multi-ball!");
multiBall.SetMenuIcon(&ballIcon);
multiBall.SetUsableInBattle();
- multiBall.SetTargettingMode(Item::TARGETTING_MODE_ENEMY | Item::TARGETTING_MODE_MULTIPLE);
+ antidote.GetTargetingMode().TargetMultipleEnemies();
inventory.Add(&multiBall, 1);
Item figgoru;
figgoru.SetName("Figgoru");
figgoru.SetMenuIcon(&crankIcon);
- figgoru.SetTargettingMode(Item::TARGETTING_MODE_ENEMY | Item::TARGETTING_MODE_ALL);
+ antidote.GetTargetingMode().TargetAllEnemies();
inventory.Add(&figgoru, 1);
battleRes.inventory = &inventory;