3 #include "../common/Spell.h"
4 #include "../common/Stats.h"
5 #include "../graphics/Animation.h"
6 #include "../graphics/Sprite.h"
7 #include "../loader/Interpreter.h"
8 #include "../loader/TypeDescription.h"
14 using graphics::Animation;
15 using graphics::Sprite;
16 using loader::FieldDescription;
17 using loader::Interpreter;
18 using loader::TypeDescription;
44 const char *Capsule::ClassName() const {
45 return GetClass().name;
48 const char *Capsule::Tribe() const {
49 return GetClass().tribe;
52 const Spell *Capsule::Attack1() const {
53 return GetClass().attacks[0];
56 const Spell *Capsule::Attack2() const {
57 return GetClass().attacks[1];
60 const Spell *Capsule::Attack3() const {
61 return GetClass().attacks[2];
65 Uint16 Capsule::MaxHealth() const {
66 return maxHealth + GetClass().healthBoost;
70 Stats Capsule::GetStats() const {
71 return stats + GetClass().statBoost;
74 int Capsule::NextLevel() const {
75 int levelOffset(Level() - 1);
76 if (levelOffset < numLevels) {
77 return levelLadder[levelOffset] - Experience();
83 void Capsule::UpgradeClass() {
88 void Capsule::NextClass() {
90 if (curClass >= maxClass) {
95 void Capsule::PreviousClass() {
98 curClass = maxClass - 1;
102 void Capsule::SetClass(int index) {
107 if (curClass >= maxClass) {
108 curClass = maxClass - 1;
113 Sprite *Capsule::BattleSprite() {
114 return GetClass().battleSprite;
117 const Sprite *Capsule::BattleSprite() const {
118 return GetClass().battleSprite;
121 Animation *Capsule::MeleeAnimation() {
122 return GetClass().meleeAnimation;
125 Animation *Capsule::AttackAnimation() {
126 return GetClass().attackAnimation;
129 Animation *Capsule::SpellAnimation() {
130 return GetClass().spellAnimation;
134 Capsule::Class &Capsule::GetClass() {
135 assert(classes && curClass < numClasses);
136 return classes[curClass];
139 const Capsule::Class &Capsule::GetClass() const {
140 assert(classes && curClass < numClasses);
141 return classes[curClass];
145 int Capsule::HungerEmpty() const {
146 return HungerTotal() - HungerFull();
149 int Capsule::HungerTotal() const {
150 return GetClass().hunger;
153 int Capsule::HungerFull() const {
154 return GetClass().hungerFull;
157 bool Capsule::IsHungry() const {
158 return HungerEmpty();
161 void Capsule::Feed(const common::Item *) {
162 // TODO: find out how to calculate an item's feed value
163 // TODO: an item the capsule favors (changes on every feed and after every
164 // battle) doubles the value
166 GetClass().hungerFull += value;
167 if (GetClass().hungerFull >= GetClass().hunger) {
168 GetClass().hungerFull = GetClass().hunger;
174 Capsule::Class::Class()
192 void Capsule::CreateTypeDescription() {
195 TypeDescription &td(TypeDescription::Create(TYPE_ID, "Capsule"));
196 td.SetConstructor(&Construct);
197 td.SetSize(sizeof(Capsule));
199 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
200 td.AddField("alignment", FieldDescription(((char *)&c.alignment) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
202 td.AddField("alignmentCursor", FieldDescription(((char *)&c.alignmentCursor) - ((char *)&c), Interpreter::VECTOR_ID));
203 td.AddField("alignmentSprite", FieldDescription(((char *)&c.alignmentSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
205 td.AddField("maxHealth", FieldDescription(((char *)&c.maxHealth) - ((char *)&c), Interpreter::NUMBER_ID));
207 td.AddField("stats", FieldDescription(((char *)&c.stats) - ((char *)&c), Stats::TYPE_ID));
209 td.AddField("level", FieldDescription(((char *)&c.level) - ((char *)&c), Interpreter::NUMBER_ID));
210 td.AddField("experience", FieldDescription(((char *)&c.experience) - ((char *)&c), Interpreter::NUMBER_ID));
212 td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), Interpreter::NUMBER_ID).SetReferenced().SetAggregate());
214 td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetReferenced().SetAggregate());
215 td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID));
216 td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID));
218 Class::CreateTypeDescription();
221 void Capsule::Construct(void *data) {
226 void Capsule::Class::CreateTypeDescription() {
229 TypeDescription &td(TypeDescription::Create(TYPE_ID, "CapsuleClass"));
230 td.SetConstructor(&Construct);
231 td.SetSize(sizeof(Class));
233 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
234 td.AddField("tribe", FieldDescription(((char *)&c.tribe) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
236 td.AddField("attack1", FieldDescription(((char *)&c.attacks[0]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
237 td.AddField("attack2", FieldDescription(((char *)&c.attacks[1]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
238 td.AddField("attack3", FieldDescription(((char *)&c.attacks[2]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
240 td.AddField("battleSprite", FieldDescription(((char *)&c.battleSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
241 td.AddField("meleeAnimation", FieldDescription(((char *)&c.meleeAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
242 td.AddField("attackAnimation", FieldDescription(((char *)&c.attackAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
243 td.AddField("spellAnimation", FieldDescription(((char *)&c.spellAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
245 td.AddField("hunger", FieldDescription(((char *)&c.hunger) - ((char *)&c), Interpreter::NUMBER_ID));
247 td.AddField("healthBoost", FieldDescription(((char *)&c.healthBoost) - ((char *)&c), Interpreter::NUMBER_ID));
248 td.AddField("statBoost", FieldDescription(((char *)&c.statBoost) - ((char *)&c), Stats::TYPE_ID));
251 void Capsule::Class::Construct(void *data) {
252 new (data) Capsule::Class;