]> git.localhorst.tv Git - l2e.git/commitdiff
added spells
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 10 Aug 2012 13:05:58 +0000 (15:05 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 10 Aug 2012 13:05:58 +0000 (15:05 +0200)
14 files changed:
Debug/src/common/subdir.mk
Release/src/common/subdir.mk
src/battle/BattleState.cpp
src/battle/BattleState.h
src/battle/Hero.h
src/battle/Resources.h
src/battle/states/SelectItem.cpp
src/common/HeroGroup.h [new file with mode: 0644]
src/common/Item.cpp
src/common/Item.h
src/common/Spell.cpp [new file with mode: 0644]
src/common/Spell.h [new file with mode: 0644]
src/common/TargetingMode.h [new file with mode: 0644]
src/main.cpp

index a4e6c46a7066f1a1f29f66ab55a82a5b679c7d82..dbcaf4941fb12e24ee822e7ce16f05d5f63e96ca 100644 (file)
@@ -5,15 +5,18 @@
 # 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
index 6ee13bc351170841ea0446fdc324e4694bbbf442..4ee363ad4a2c039e6370764dd4757edbe92db7d7 100644 (file)
@@ -5,15 +5,18 @@
 # 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
index ad225173fce209625a452265c0913cf5b1d9adda..c54fecaca88dd10acdb79ff16b597fe82a6d7cf5 100644 (file)
@@ -13,6 +13,7 @@
 #include "../app/Input.h"
 #include "../common/Inventory.h"
 #include "../common/Item.h"
+#include "../common/Spell.h"
 #include "../geometry/operators.h"
 #include "../graphics/Sprite.h"
 
@@ -22,6 +23,7 @@ using app::Application;
 using app::Input;
 using common::Inventory;
 using common::Item;
+using common::Spell;
 using geometry::Point;
 using geometry::Vector;
 using graphics::Menu;
@@ -55,7 +57,7 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) {
        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));
@@ -74,6 +76,15 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) {
        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();
index 1a0586c9025e31b42113468bc06c50e607517bfe..ff0672da84a2f365b8379455437c109e72779c41 100644 (file)
@@ -27,6 +27,7 @@ namespace app { class Input; }
 namespace common {
        class Inventory;
        class Item;
+       class Spell;
 }
 namespace graphics {
        class Font;
@@ -92,8 +93,8 @@ public:
        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; }
@@ -121,6 +122,7 @@ public:
        void RenderHeroTags(SDL_Surface *screen, const geometry::Vector<int> &offset);
 
 private:
+       void LoadSpellMenu(std::vector<Hero>::size_type heroIndex);
        void LoadInventory();
 
 private:
@@ -135,7 +137,7 @@ 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];
index 69db286c74d32fb69fa64a8ffe575439e90c0d4b..03f909519400ffac8685e92b9b97301fd29425ae 100644 (file)
@@ -8,8 +8,10 @@
 #ifndef BATTLE_HERO_H_
 #define BATTLE_HERO_H_
 
+#include <vector>
 #include <SDL.h>
 
+namespace common { class Spell; }
 namespace graphics { class Sprite; }
 
 namespace battle {
@@ -25,6 +27,8 @@ public:
        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; }
@@ -56,10 +60,15 @@ public:
        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;
index c0fb48cf159bec8ca258ab68f8eed59b37a8fcea..bd2fd91358839249062177d71d405ee30e316ab0 100644 (file)
@@ -13,6 +13,7 @@
 namespace common {
        class Inventory;
        class Item;
+       class Spell;
 }
 namespace graphics {
        class Font;
@@ -50,7 +51,7 @@ struct Resources {
        graphics::Sprite *itemTargetCursor;
 
        const char *spellMenuHeadline;
-       graphics::Menu</* Spell */ void *> spellMenuPrototype;
+       graphics::Menu<const common::Spell *> spellMenuPrototype;
 
        common::Inventory *inventory;
        const char *itemMenuHeadline;
index a2d178eb251f83db906d7c662ddf34c3606c6322..97dd63fc33a53d90c32882ba37bba7e2f462d3c0 100644 (file)
@@ -55,19 +55,19 @@ void SelectItem::HandleInput(const Input &input) {
                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();
diff --git a/src/common/HeroGroup.h b/src/common/HeroGroup.h
new file mode 100644 (file)
index 0000000..ef6fd25
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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_ */
index 65df4c8ed08660b549bd7d770eada87723997fc1..dcad7de6f0d5dd850a1cd80a1b5ce7ea49dbea3d 100644 (file)
 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) {
 
 }
 
index 1dde8878f7c0d4f2dfe79fcd80e516ec150f4edd..0542acc6a2dacc1c9999ce871167d1055402e4e4 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef COMMON_ITEM_H_
 #define COMMON_ITEM_H_
 
+#include "HeroGroup.h"
+#include "TargetingMode.h"
+
 #include <SDL.h>
 
 namespace graphics { class Sprite; }
@@ -32,11 +35,8 @@ public:
        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; }
@@ -52,16 +52,11 @@ public:
        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; }
@@ -79,9 +74,8 @@ public:
        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,
@@ -92,15 +86,6 @@ public:
                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,
@@ -110,19 +95,9 @@ public:
                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,
@@ -148,9 +123,9 @@ private:
        Uint16 properties;
 
        Uint8 usability;
-       Uint8 targettingMode;
+       TargetingMode targettingMode;
        Uint8 equipable;
-       Uint8 equipableBy;
+       HeroGroup equipableBy;
 
 };
 
diff --git a/src/common/Spell.cpp b/src/common/Spell.cpp
new file mode 100644 (file)
index 0000000..f347774
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Spell.cpp
+ *
+ *  Created on: Aug 10, 2012
+ *      Author: holy
+ */
+
+#include "Spell.h"
+
+namespace common {
+
+Spell::Spell()
+: name(""), value(0), cost(0), usability(0) {
+
+}
+
+}
diff --git a/src/common/Spell.h b/src/common/Spell.h
new file mode 100644 (file)
index 0000000..38d2395
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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_ */
diff --git a/src/common/TargetingMode.h b/src/common/TargetingMode.h
new file mode 100644 (file)
index 0000000..5376d13
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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_ */
index 20579d817c0f8e1c871d7bf48765374225110ad3..3c871cd862fc169fba7221ccc3515d80373ad7eb 100644 (file)
@@ -14,6 +14,7 @@
 #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"
@@ -37,6 +38,7 @@ using battle::Monster;
 using battle::PartyLayout;
 using common::Inventory;
 using common::Item;
+using common::Spell;
 using geometry::Point;
 using graphics::Font;
 using graphics::Frame;
@@ -204,15 +206,46 @@ int main(int argc, char **argv) {
                // 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);
@@ -245,19 +278,19 @@ int main(int argc, char **argv) {
                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");
@@ -270,18 +303,18 @@ int main(int argc, char **argv) {
                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;