]> git.localhorst.tv Git - l2e.git/commitdiff
extracted common capsule base
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 2 Dec 2012 20:36:13 +0000 (21:36 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 2 Dec 2012 20:38:47 +0000 (21:38 +0100)
13 files changed:
l2e.cbp
src/battle/BattleState.cpp
src/battle/Capsule.cpp
src/battle/Capsule.h
src/common/Capsule.cpp [new file with mode: 0644]
src/common/Capsule.h [new file with mode: 0644]
src/common/Stats.h
src/common/fwd.h
src/loader/Caster.cpp
src/loader/Caster.h
src/main.cpp
test-data/capsules.l2h [new file with mode: 0644]
test-data/capsules.l2s [new file with mode: 0644]

diff --git a/l2e.cbp b/l2e.cbp
index 7b8f77bd94333d4e36a0e14298cc4f57e9499ee9..d3ab9a3cb48382c683e63742c73dddcaa3cd0c37 100644 (file)
--- a/l2e.cbp
+++ b/l2e.cbp
@@ -11,7 +11,7 @@
                                <Option object_output="obj\W32_Debug\" />
                                <Option type="1" />
                                <Option compiler="gcc" />
-                               <Option parameters="test-data/constants.l2s  test-data/ikaris.l2s  test-data/items.l2s  test-data/maps.l2s  test-data/spells.l2s  test-data/test.l2s" />
+                               <Option parameters="test-data/capsules.l2s  test-data/constants.l2s  test-data/ikaris.l2s  test-data/items.l2s  test-data/maps.l2s  test-data/spells.l2s  test-data/test.l2s" />
                                <Option projectLinkerOptionsRelation="2" />
                                <Compiler>
                                        <Add option="-g" />
@@ -30,7 +30,7 @@
                                <Option object_output="obj\W32\" />
                                <Option type="1" />
                                <Option compiler="gcc" />
-                               <Option parameters="test-data/constants.l2s  test-data/ikaris.l2s  test-data/items.l2s  test-data/maps.l2s  test-data/spells.l2s  test-data/test.l2s" />
+                               <Option parameters="test-data/capsules.l2s  test-data/constants.l2s  test-data/ikaris.l2s  test-data/items.l2s  test-data/maps.l2s  test-data/spells.l2s  test-data/test.l2s" />
                                <Option projectLinkerOptionsRelation="2" />
                                <Compiler>
                                        <Add option="-O3" />
@@ -68,6 +68,8 @@
                <Unit filename="src\battle\AttackTypeMenu.h" />
                <Unit filename="src\battle\BattleState.cpp" />
                <Unit filename="src\battle\BattleState.h" />
+               <Unit filename="src\battle\Capsule.cpp" />
+               <Unit filename="src\battle\Capsule.h" />
                <Unit filename="src\battle\Hero.cpp" />
                <Unit filename="src\battle\Hero.h" />
                <Unit filename="src\battle\HeroTag.cpp" />
                <Unit filename="src\battle\states\SelectTarget.h" />
                <Unit filename="src\battle\states\SwapHeroes.cpp" />
                <Unit filename="src\battle\states\SwapHeroes.h" />
+               <Unit filename="src\common\Capsule.cpp" />
+               <Unit filename="src\common\Capsule.h" />
                <Unit filename="src\common\GameConfig.cpp" />
                <Unit filename="src\common\GameConfig.h" />
                <Unit filename="src\common\GameState.cpp" />
index 0171e1480f56a7d52b905a86e577525d0a2597a0..085a85371530678e0d578fa1fb8560aeb3299382 100644 (file)
@@ -192,7 +192,7 @@ void BattleState::CalculateAttackOrder() {
                attackOrder.push_back(Order(Order::MONSTER, i));
                MonsterAt(i).GetAttackChoice() = AttackChoice(this);
        }
-       if (capsule.Health() > 0) {
+       if (capsule.Active() && capsule.Health() > 0) {
                attackOrder.push_back(Order(Order::CAPSULE));
        }
        std::sort(attackOrder.begin(), attackOrder.end(), OrderCompare(this));
@@ -210,7 +210,7 @@ void BattleState::NextAttack() {
                } else if (attackOrder[attackCursor].IsHero()) {
                        if (HeroAt(attackOrder[attackCursor].index).Health() > 0) break;
                } else {
-                       if (capsule.Health() > 0) break;
+                       if (capsule.Active() && capsule.Health() > 0) break;
                }
                ++attackCursor;
        }
@@ -438,7 +438,7 @@ void BattleState::RenderHeroes(SDL_Surface *screen, const Vector<int> &offset) {
 }
 
 void BattleState::RenderCapsule(SDL_Surface *screen, const Vector<int> &offset) {
-       if (capsule.Health() <= 0) return;
+       if (!capsule.Active() || capsule.Health() <= 0) return;
        if (capsule.GetAnimation().Running()) {
                capsule.GetAnimation().DrawCenter(screen, capsule.Position() + offset);
        } else {
index 709ef3bf0af340cbf36adfb10f4eb5cfa7269c47..ef85ae17b22a88a45a52b6f42bd6aba6356754cd 100644 (file)
@@ -1,24 +1,66 @@
 #include "Capsule.h"
 
+#include "../common/Capsule.h"
+
+#include <cassert>
+
+using graphics::Animation;
+using graphics::Sprite;
+
 namespace battle {
 
-Capsule::Capsule()
-: name(0)
+Capsule::Capsule(common::Capsule *master)
+: master(master)
+, health(master ? master->MaxHealth() : 0) {
+       if (master) {
+               stats = master->GetStats();
+       }
+}
+
 
-, maxHealth(0)
-, health(0)
-, maxMana(0)
-, mana(0)
+const char *Capsule::Name() const {
+       assert(master);
+       return master->Name();
+}
 
-, level(0)
+Uint8 Capsule::Level() const {
+       assert(master);
+       return master->Level();
+}
 
-, battleSprite(0)
-, meleeAnimation(0)
-, attackAnimation(0)
-, spellAnimation(0) {
+const Sprite *Capsule::Sprite() {
+       assert(master);
+       return master->BattleSprite();
+}
 
+const Animation *Capsule::MeleeAnimation() const {
+       assert(master);
+       return master->MeleeAnimation();
 }
 
+const Animation *Capsule::AttackAnimation() const {
+       assert(master);
+       return master->AttackAnimation();
+}
+
+const Animation *Capsule::SpellAnimation() const {
+       assert(master);
+       return master->SpellAnimation();
+}
+
+
+Uint16 Capsule::MaxHealth() const {
+       assert(master);
+       return master->MaxHealth();
+}
+
+Uint16 Capsule::Health() const {
+       return health;
+}
+
+int Capsule::RelativeHealth(int max) const {
+       return Health() * max / MaxHealth();
+}
 
 void Capsule::SubtractHealth(int amount) {
        if (amount > health) {
index c5050f7be59548da08076876132139c486f8e0f2..7438492bc7f86a7046b999fc42ee4fb8e8755b18 100644 (file)
@@ -1,8 +1,11 @@
 #ifndef BATTLE_CAPSULE_H_
 #define BATTLE_CAPSULE_H_
 
+namespace common {
+       class Capsule;
+}
+
 #include "AttackChoice.h"
-#include "../common/fwd.h"
 #include "../common/Stats.h"
 #include "../geometry/Vector.h"
 #include "../graphics/Animation.h"
@@ -14,22 +17,19 @@ namespace battle {
 class Capsule {
 
 public:
-       Capsule();
+       Capsule(common::Capsule *master = 0);
 
 public:
-       const char *Name() const { return name; }
-       Uint8 Level() const { return level; }
-       const graphics::Sprite *Sprite() const { return battleSprite; }
+       bool Active() const { return master; }
 
-       Uint16 MaxHealth() const { return maxHealth; }
-       Uint16 Health() const { return health; }
-       int RelativeHealth(int max) const { return Health() * max / MaxHealth(); }
-       void SubtractHealth(int amount);
+       const char *Name() const;
+       Uint8 Level() const;
+       const graphics::Sprite *Sprite();
 
-       Uint16 MaxMana() const { return maxMana; }
-       Uint16 Mana() const { return mana; }
-       int RelativeMana(int max) const { return MaxMana() == 0 ? 0 : Mana() * max / MaxMana(); }
-       bool CanUseMagic() const { return MaxMana() > 0; }
+       Uint16 MaxHealth() const;
+       Uint16 Health() const;
+       int RelativeHealth(int max) const;
+       void SubtractHealth(int amount);
 
        common::Stats &GetStats() { return stats; }
        const common::Stats &GetStats() const { return stats; }
@@ -38,9 +38,9 @@ public:
        const graphics::AnimationRunner &GetAnimation() const { return animation; }
        void SetAnimation(const graphics::AnimationRunner &a) { animation = a; }
 
-       const graphics::Animation *MeleeAnimation() const { return meleeAnimation; }
-       const graphics::Animation *AttackAnimation() const { return attackAnimation; }
-       const graphics::Animation *SpellAnimation() const { return spellAnimation; }
+       const graphics::Animation *MeleeAnimation() const;
+       const graphics::Animation *AttackAnimation() const;
+       const graphics::Animation *SpellAnimation() const;
 
        geometry::Vector<int> &Position() { return position; }
        const geometry::Vector<int> &Position() const { return position; }
@@ -48,29 +48,10 @@ public:
        AttackChoice &GetAttackChoice() { return attackChoice; }
        const AttackChoice &GetAttackChoice() const { return attackChoice; }
 
-// temporary setters
-public:
-       void SetName(const char *n) { name = n; }
-       void SetHealth(int max, int cur) { maxHealth = max; health = cur; }
-       void SetMana(int max, int cur) { maxMana = max; mana = cur; }
-       void SetLevel(int l) { level = l; }
-       void SetBattleSprite(graphics::Sprite *s) { battleSprite = s; }
-       void SetMeleeAnimation(graphics::Animation *a) { meleeAnimation = a; }
-       void SetAttackAnimation(graphics::Animation *a) { attackAnimation = a; }
-       void SetSpellAnimation(graphics::Animation *a) { spellAnimation = a; }
-
 private:
-       const char *name;
-
-       int maxHealth, health;
-       int maxMana, mana;
-
-       int level;
+       common::Capsule *master;
 
-       graphics::Sprite *battleSprite;
-       graphics::Animation *meleeAnimation;
-       graphics::Animation *attackAnimation;
-       graphics::Animation *spellAnimation;
+       int health;
 
        graphics::AnimationRunner animation;
        geometry::Vector<int> position;
diff --git a/src/common/Capsule.cpp b/src/common/Capsule.cpp
new file mode 100644 (file)
index 0000000..a944e70
--- /dev/null
@@ -0,0 +1,166 @@
+#include "Capsule.h"
+
+#include "../common/Spell.h"
+#include "../common/Stats.h"
+#include "../graphics/Animation.h"
+#include "../graphics/Sprite.h"
+#include "../loader/Interpreter.h"
+#include "../loader/TypeDescription.h"
+
+#include <cassert>
+
+using common::Spell;
+using common::Stats;
+using graphics::Animation;
+using graphics::Sprite;
+using loader::FieldDescription;
+using loader::Interpreter;
+using loader::TypeDescription;
+
+namespace common {
+
+Capsule::Capsule()
+: name("")
+, alignment("")
+
+, maxHealth(0)
+
+, level(1)
+, experience(0)
+
+, levelLadder(0)
+, numLevels(0)
+
+, classes(0)
+, numClasses(0)
+, curClass(0)
+, maxClass(0) {
+
+}
+
+
+Uint16 Capsule::MaxHealth() const {
+       return maxHealth + GetClass().healthBoost;
+}
+
+
+Stats Capsule::GetStats() {
+       return stats + GetClass().statBoost;
+}
+
+int Capsule::NextLevel() const {
+       int levelOffset(Level() - 1);
+       if (levelOffset < numLevels) {
+               return levelLadder[levelOffset] - Experience();
+       } else {
+               return 0;
+       }
+}
+
+
+Sprite *Capsule::BattleSprite() {
+       return GetClass().battleSprite;
+}
+
+const Sprite *Capsule::BattleSprite() const {
+       return GetClass().battleSprite;
+}
+
+Animation *Capsule::MeleeAnimation() {
+       return GetClass().meleeAnimation;
+}
+
+Animation *Capsule::AttackAnimation() {
+       return GetClass().attackAnimation;
+}
+
+Animation *Capsule::SpellAnimation() {
+       return GetClass().spellAnimation;
+}
+
+
+Capsule::Class &Capsule::GetClass() {
+       assert(classes && curClass < numClasses);
+       return classes[curClass];
+}
+
+const Capsule::Class &Capsule::GetClass() const {
+       assert(classes && curClass < numClasses);
+       return classes[curClass];
+}
+
+
+Capsule::Class::Class()
+: name(0)
+, tribe(0)
+, battleSprite(0)
+, meleeAnimation(0)
+, attackAnimation(0)
+, spellAnimation(0)
+
+, healthBoost(0) {
+       attacks[0] = 0;
+       attacks[1] = 0;
+       attacks[2] = 0;
+}
+
+
+void Capsule::CreateTypeDescription() {
+       Capsule c;
+
+       TypeDescription &td(TypeDescription::Create(TYPE_ID, "Capsule"));
+       td.SetConstructor(&Construct);
+       td.SetSize(sizeof(Capsule));
+
+       td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
+       td.AddField("alignment", FieldDescription(((char *)&c.alignment) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
+
+       td.AddField("maxHealth", FieldDescription(((char *)&c.maxHealth) - ((char *)&c), Interpreter::NUMBER_ID));
+
+       td.AddField("stats", FieldDescription(((char *)&c.stats) - ((char *)&c), Stats::TYPE_ID));
+
+       td.AddField("level", FieldDescription(((char *)&c.level) - ((char *)&c), Interpreter::NUMBER_ID));
+       td.AddField("experience", FieldDescription(((char *)&c.experience) - ((char *)&c), Interpreter::NUMBER_ID));
+
+       td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), Interpreter::NUMBER_ID).SetReferenced().SetAggregate());
+
+       td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetReferenced().SetAggregate());
+       td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID));
+       td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID));
+
+       Class::CreateTypeDescription();
+}
+
+void Capsule::Construct(void *data) {
+       new (data) Capsule;
+}
+
+
+void Capsule::Class::CreateTypeDescription() {
+       Class c;
+
+       TypeDescription &td(TypeDescription::Create(TYPE_ID, "CapsuleClass"));
+       td.SetConstructor(&Construct);
+       td.SetSize(sizeof(Class));
+
+       td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
+       td.AddField("tribe", FieldDescription(((char *)&c.tribe) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
+
+       td.AddField("attack1", FieldDescription(((char *)&c.attacks[0]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
+       td.AddField("attack2", FieldDescription(((char *)&c.attacks[1]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
+       td.AddField("attack3", FieldDescription(((char *)&c.attacks[2]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
+
+       td.AddField("battleSprite", FieldDescription(((char *)&c.battleSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
+       td.AddField("meleeAnimation", FieldDescription(((char *)&c.meleeAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
+       td.AddField("attackAnimation", FieldDescription(((char *)&c.attackAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
+       td.AddField("spellAnimation", FieldDescription(((char *)&c.spellAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
+
+       td.AddField("healthBoost", FieldDescription(((char *)&c.healthBoost) - ((char *)&c), Interpreter::NUMBER_ID));
+       td.AddField("statBoost", FieldDescription(((char *)&c.statBoost) - ((char *)&c), Stats::TYPE_ID));
+}
+
+void Capsule::Class::Construct(void *data) {
+       new (data) Capsule::Class;
+}
+
+}
diff --git a/src/common/Capsule.h b/src/common/Capsule.h
new file mode 100644 (file)
index 0000000..575a40c
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef COMMON_CAPSULE_H_
+#define COMMON_CAPSULE_H_
+
+namespace graphics {
+       class Animation;
+       class Sprite;
+}
+
+#include "../common/Stats.h"
+
+#include <SDL.h>
+
+namespace common {
+
+class Spell;
+
+class Capsule {
+
+public:
+       static const int TYPE_ID = 307;
+
+public:
+       Capsule();
+
+       const char *Name() const { return name; }
+       const char *Alignment() const { return alignment; }
+
+       Uint16 MaxHealth() const;
+
+       Stats GetStats();
+
+       Uint8 Level() const { return level; }
+       int Experience() const { return experience; }
+       int NextLevel() const;
+
+       graphics::Sprite *BattleSprite();
+       const graphics::Sprite *BattleSprite() const;
+       graphics::Animation *MeleeAnimation();
+       graphics::Animation *AttackAnimation();
+       graphics::Animation *SpellAnimation();
+
+       static void CreateTypeDescription();
+       static void Construct(void *);
+
+private:
+       struct Class {
+               static const int TYPE_ID = 308;
+
+               Class();
+
+               static void CreateTypeDescription();
+               static void Construct(void *);
+
+               const char *name;
+               const char *tribe;
+               Spell *attacks[3];
+               graphics::Sprite *battleSprite;
+               graphics::Animation *meleeAnimation;
+               graphics::Animation *attackAnimation;
+               graphics::Animation *spellAnimation;
+
+               int healthBoost;
+               Stats statBoost;
+       };
+
+       Class &GetClass();
+       const Class &GetClass() const;
+
+       const char *name;
+       const char *alignment;
+
+       int maxHealth;
+
+       Stats stats;
+
+       int level;
+       int experience;
+
+       int *levelLadder;
+       int numLevels;
+
+       Class *classes;
+       int numClasses, curClass, maxClass;
+
+};
+
+}
+
+#endif /* COMMON_CAPSULE_H_ */
index 3d813120381c5938d3e42bd5b4897bc7294f1775..6374c3540d5e43dc4861c1257f8966a27cf6d6e8 100644 (file)
@@ -45,6 +45,18 @@ private:
 
 };
 
+
+inline Stats operator +(const Stats &lhs, const Stats &rhs) {
+       return Stats(
+                       lhs.Attack() + rhs.Attack(),
+                       lhs.Defense() + rhs.Defense(),
+                       lhs.Strength() + rhs.Strength(),
+                       lhs.Agility() + rhs.Agility(),
+                       lhs.Intelligence() + rhs.Intelligence(),
+                       lhs.Gut() + rhs.Gut(),
+                       lhs.MagicResistance() + rhs.MagicResistance());
+}
+
 }
 
 #endif /* COMMON_STATS_H_ */
index 5b9be8200172f22cf6359fb37f433ae6b9b3bb7e..209eaa158b083d87fd0d4f77ae79716d077215b3 100644 (file)
@@ -3,6 +3,7 @@
 
 namespace common {
 
+class Capsule;
 struct GameConfig;
 struct GameState;
 class Hero;
index 78a31b548db4737e0cd4cba08ee104fd73a9313f..050ac930e9ef956d90bb16763fd94a47e02697b5 100644 (file)
@@ -4,6 +4,7 @@
 #include "../battle/Resources.h"
 #include "../battle/Monster.h"
 #include "../battle/PartyLayout.h"
+#include "../common/Capsule.h"
 #include "../common/Hero.h"
 #include "../common/Item.h"
 #include "../common/Spell.h"
@@ -12,6 +13,7 @@
 
 using battle::Monster;
 using battle::PartyLayout;
+using common::Capsule;
 using common::Hero;
 using common::Item;
 using common::Spell;
@@ -32,6 +34,10 @@ battle::Resources *Caster::GetBattleResources(const string &ident) {
                        intp.GetObject(battle::Resources::TYPE_ID, ident));
 }
 
+Capsule *Caster::GetCapsule(const string &ident) {
+       return reinterpret_cast<Capsule *>(intp.GetObject(Capsule::TYPE_ID, ident));
+}
+
 Hero *Caster::GetHero(const string &ident) {
        return reinterpret_cast<Hero *>(intp.GetObject(Hero::TYPE_ID, ident));
 }
index 2aa6be09ed5762d8dae481bf321813d10f94e851..31ce61226677f40f8d32645bbf1d861e6680f3bf 100644 (file)
@@ -22,6 +22,7 @@ private:
 
 public:
        battle::Resources *GetBattleResources(const std::string &identifier);
+       common::Capsule *GetCapsule(const std::string &identifier);
        common::Hero *GetHero(const std::string &identifier);
        common::Item *GetItem(const std::string &identifier);
        map::Map *GetMap(const std::string &identifier);
index 53301ce5f5c785fa7c97d6d49f047936fa35e91c..8c099918aa5fac8586d88db10ba58e7baef673c5 100644 (file)
@@ -7,6 +7,7 @@
 #include "battle/Monster.h"
 #include "battle/PartyLayout.h"
 #include "battle/Resources.h"
+#include "common/Capsule.h"
 #include "common/GameConfig.h"
 #include "common/GameState.h"
 #include "common/Hero.h"
@@ -54,9 +55,9 @@ using app::Application;
 using app::Arguments;
 using app::Input;
 using battle::BattleState;
-using battle::Capsule;
 using battle::Monster;
 using battle::PartyLayout;
+using common::Capsule;
 using common::GameConfig;
 using common::GameState;
 using common::Hero;
@@ -101,6 +102,7 @@ int main(int argc, char **argv) {
                battle::Monster::CreateTypeDescription();
                battle::PartyLayout::CreateTypeDescription();
 
+               common::Capsule::CreateTypeDescription();
                common::Hero::CreateTypeDescription();
                common::Ikari::CreateTypeDescription();
                common::Item::CreateTypeDescription();
@@ -279,29 +281,6 @@ int main(int argc, char **argv) {
                gameState.heroes[3].MapEntity().SetFlags(Entity::FLAG_NONBLOCKING);
                gameState.heroes[2].MapEntity().AddFollower(&gameState.heroes[3].MapEntity());
 
-               graphics::Sprite flashSprite(IMG_Load("test-data/flash.png"), 96, 96);
-               graphics::ComplexAnimation flashAttackAnimation(&flashSprite, 132);
-               graphics::ComplexAnimation::FrameProp flashAttackFrames[4];
-               flashAttackFrames[0] = graphics::ComplexAnimation::FrameProp(0, 1, Vector<int>(0, -16));
-               flashAttackFrames[1] = graphics::ComplexAnimation::FrameProp(0, 0, Vector<int>(0, -16));
-               flashAttackFrames[2] = graphics::ComplexAnimation::FrameProp(0, 1, Vector<int>(0, -16));
-               flashAttackFrames[3] = graphics::ComplexAnimation::FrameProp(0, 0, Vector<int>(0, -16));
-               flashAttackAnimation.SetFrames(flashAttackFrames, 4);
-               Capsule capsule;
-               capsule.SetName("Flash");
-               capsule.SetHealth(5, 5);
-               capsule.SetLevel(1);
-               capsule.GetStats().SetAttack(12);
-               capsule.GetStats().SetDefense(18);
-               capsule.GetStats().SetStrength(2);
-               capsule.GetStats().SetAgility(11);
-               capsule.GetStats().SetIntelligence(16);
-               capsule.GetStats().SetGut(23);
-               capsule.GetStats().SetMagicResistance(11);
-               capsule.SetBattleSprite(&flashSprite);
-               capsule.SetAttackAnimation(&flashAttackAnimation);
-               capsule.SetMeleeAnimation(gameState.heroes[0].MeleeAnimation());
-
                InitScreen screen(width, height);
 
                app::State *state(0);
@@ -312,7 +291,7 @@ int main(int argc, char **argv) {
                        battleState->AddMonster(monster);
                        battleState->AddMonster(monster);
                        battleState->AddMonster(monster);
-                       battleState->SetCapsule(capsule);
+                       battleState->SetCapsule(caster.GetCapsule("flash"));
                        battleState->AddHero(gameState.heroes[0]);
                        battleState->AddHero(gameState.heroes[1]);
                        battleState->AddHero(gameState.heroes[2]);
diff --git a/test-data/capsules.l2h b/test-data/capsules.l2h
new file mode 100644 (file)
index 0000000..e996696
--- /dev/null
@@ -0,0 +1 @@
+Capsule flash
diff --git a/test-data/capsules.l2s b/test-data/capsules.l2s
new file mode 100644 (file)
index 0000000..a4f525e
--- /dev/null
@@ -0,0 +1,56 @@
+Sprite flashSprite {
+       image: :"flash.png",
+       size: <96, 96>
+}
+
+export Capsule flash {
+       name: "Flash",
+       alignment: "LIGHT",
+       maxHealth: 5,
+       stats: Stats {
+               atp: 12,
+               dfp: 18,
+               str:  2,
+               agl: 11,
+               int: 16,
+               gut: 23,
+               mgr: 11
+       },
+       classes: [ CapsuleClass
+               {
+                       name: "4",
+                       tribe: "Twinkle",
+                       battleSprite: flashSprite,
+                       meleeAnimation: SimpleAnimation {
+                               sprite: Sprite {
+                                       image: :"melee-maxim.png",
+                                       size: <96,96>
+                               },
+                               frametime: 66, // two "frames"
+                               framecount: 4
+                       },
+                       attackAnimation: ComplexAnimation {
+                               sprite: flashSprite,
+                               frametime: fourFramesTime,
+                               repeat: false,
+                               frames:
+                               [ ComplexAnimationFrame
+                                       { column: 0, row: 1, disposition: < 0, -16> },
+                                       { column: 0, row: 0, disposition: < 0, -16> },
+                                       { column: 0, row: 1, disposition: < 0, -16> },
+                                       { column: 0, row: 0, disposition: < 0, -16> }
+                               ]
+                       },
+                       healthBoost: 208,
+                       statBoost: Stats {
+                               atp:  38,
+                               dfp:  71,
+                               str:  24,
+                               agl:  78,
+                               int: 195,
+                               gut:  12, // TODO: this is probably higher, but clipped at 199
+                               mgr: 135
+                       }
+               }
+       ]
+}