7 #include "../graphics/Animation.h"
8 #include "../graphics/Sprite.h"
9 #include "../loader/Interpreter.h"
10 #include "../loader/TypeDescription.h"
16 using graphics::Animation;
17 using graphics::Sprite;
18 using loader::FieldDescription;
19 using loader::Interpreter;
20 using loader::TypeDescription;
47 const char *Capsule::ClassName() const {
48 return GetClass().name;
51 const char *Capsule::Tribe() const {
52 return GetClass().tribe;
55 const Spell *Capsule::Attack1() const {
56 return GetClass().attacks[0];
59 const Spell *Capsule::Attack2() const {
60 return GetClass().attacks[1];
63 const Spell *Capsule::Attack3() const {
64 return GetClass().attacks[2];
68 Uint16 Capsule::MaxHealth() const {
69 return maxHealth + GetClass().healthBoost;
73 Stats Capsule::GetStats() const {
74 return stats + GetClass().statBoost;
77 int Capsule::NextLevel() const {
78 int levelOffset(Level() - 1);
79 if (levelOffset < numLevels) {
80 return levelLadder[levelOffset].Experience() - Experience();
86 void Capsule::AddExperience(int exp, vector<Upgrade> &info) {
87 if (level > numLevels) {
88 // don't award any experience if at highest level
89 info.push_back(Upgrade(
90 name, Upgrade::LEVEL_NEXT, NextLevel()));
94 while (remain >= NextLevel()) {
95 const LevelUp &lup = levelLadder[level - 1];
96 int added = NextLevel();
100 maxHealth += lup.MaxHealth();
103 info.push_back(Upgrade(name, Upgrade::LEVEL_UP, level));
105 if (lup.MaxHealth() > 0) {
106 info.push_back(Upgrade(name, Upgrade::MAX_HEALTH, lup.MaxHealth()));
108 if (lup.Attack() > 0) {
109 info.push_back(Upgrade(name, Upgrade::ATTACK, lup.Attack()));
111 if (lup.Defense() > 0) {
112 info.push_back(Upgrade(name, Upgrade::DEFENSE, lup.Defense()));
114 if (lup.Strength() > 0) {
115 info.push_back(Upgrade(name, Upgrade::STRENGTH, lup.Strength()));
117 if (lup.Agility() > 0) {
118 info.push_back(Upgrade(name, Upgrade::AGILITY, lup.Agility()));
120 if (lup.Intelligence() > 0) {
121 info.push_back(Upgrade(name, Upgrade::INTELLIGENCE, lup.Intelligence()));
124 info.push_back(Upgrade(name, Upgrade::GUT, lup.Gut()));
126 if (lup.MagicResistance() > 0) {
127 info.push_back(Upgrade(name, Upgrade::MAGIC_RESISTANCE, lup.MagicResistance()));
130 if (level > numLevels) {
131 info.push_back(Upgrade(
132 name, Upgrade::LEVEL_NEXT, NextLevel()));
136 experience += remain;
137 info.push_back(Upgrade(
138 name, Upgrade::LEVEL_NEXT, NextLevel()));
142 void Capsule::UpgradeClass() {
147 void Capsule::NextClass() {
148 if (maxClass == numClasses) {
152 if (curClass >= maxClass) {
157 void Capsule::PreviousClass() {
158 if (maxClass == numClasses) {
163 curClass = maxClass - 1;
167 void Capsule::SetClass(int index) {
168 if (maxClass == numClasses) {
175 if (curClass >= maxClass) {
176 curClass = maxClass - 1;
181 Sprite *Capsule::BattleSprite() {
182 return GetClass().battleSprite;
185 const Sprite *Capsule::BattleSprite() const {
186 return GetClass().battleSprite;
189 Animation *Capsule::MeleeAnimation() {
190 return GetClass().meleeAnimation;
193 Animation *Capsule::AttackAnimation() {
194 return GetClass().attackAnimation;
197 Animation *Capsule::SpellAnimation() {
198 return GetClass().spellAnimation;
202 Capsule::Class &Capsule::GetClass() {
203 assert(classes && curClass < numClasses);
204 return classes[curClass];
207 const Capsule::Class &Capsule::GetClass() const {
208 assert(classes && curClass < numClasses);
209 return classes[curClass];
213 int Capsule::HungerEmpty() const {
214 return HungerTotal() - HungerFull();
217 int Capsule::HungerTotal() const {
218 return GetClass().hunger;
221 int Capsule::HungerFull() const {
222 return GetClass().hungerFull;
225 bool Capsule::IsHungry() const {
226 return HungerEmpty();
229 void Capsule::Feed(const common::Item *item) {
230 // TODO: find out how to calculate an item's feed value
231 // TODO: an item the capsule favors (changes on every feed and after every
232 // battle) doubles the value
234 GetClass().hungerFull += value;
235 if (GetClass().hungerFull >= GetClass().hunger) {
236 GetClass().hungerFull = GetClass().hunger;
241 const common::Item *Capsule::UpgradeItem() const {
242 return GetClass().upgradeItem;
245 void Capsule::UpgradeSpecial() {
246 maxClass = GetClass().upgradeClass + 1;
247 curClass = GetClass().upgradeClass;
251 Capsule::Class::Class()
272 void Capsule::CreateTypeDescription() {
275 TypeDescription &td(TypeDescription::Create(TYPE_ID, "Capsule"));
276 td.SetConstructor(&Construct);
277 td.SetSize(sizeof(Capsule));
279 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
280 td.AddField("alignment", FieldDescription(((char *)&c.alignment) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
282 td.AddField("alignmentCursor", FieldDescription(((char *)&c.alignmentCursor) - ((char *)&c), Interpreter::VECTOR_ID));
283 td.AddField("alignmentSprite", FieldDescription(((char *)&c.alignmentSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
285 td.AddField("maxHealth", FieldDescription(((char *)&c.maxHealth) - ((char *)&c), Interpreter::NUMBER_ID));
287 td.AddField("stats", FieldDescription(((char *)&c.stats) - ((char *)&c), Stats::TYPE_ID));
289 td.AddField("level", FieldDescription(((char *)&c.level) - ((char *)&c), Interpreter::NUMBER_ID));
290 td.AddField("experience", FieldDescription(((char *)&c.experience) - ((char *)&c), Interpreter::NUMBER_ID));
292 td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), LevelUp::TYPE_ID).SetAggregate());
294 td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetAggregate());
295 td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID));
296 td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID));
298 Class::CreateTypeDescription();
301 void Capsule::Construct(void *data) {
306 void Capsule::Class::CreateTypeDescription() {
309 TypeDescription &td(TypeDescription::Create(TYPE_ID, "CapsuleClass"));
310 td.SetConstructor(&Construct);
311 td.SetSize(sizeof(Class));
313 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
314 td.AddField("tribe", FieldDescription(((char *)&c.tribe) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
316 td.AddField("attack1", FieldDescription(((char *)&c.attacks[0]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
317 td.AddField("attack2", FieldDescription(((char *)&c.attacks[1]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
318 td.AddField("attack3", FieldDescription(((char *)&c.attacks[2]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
320 td.AddField("battleSprite", FieldDescription(((char *)&c.battleSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
321 td.AddField("meleeAnimation", FieldDescription(((char *)&c.meleeAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
322 td.AddField("attackAnimation", FieldDescription(((char *)&c.attackAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
323 td.AddField("spellAnimation", FieldDescription(((char *)&c.spellAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
325 td.AddField("upgradeItem", FieldDescription(((char *)&c.upgradeItem) - ((char *)&c), common::Item::TYPE_ID).SetReferenced());
326 td.AddField("upgradeClass", FieldDescription(((char *)&c.upgradeClass) - ((char *)&c), Interpreter::NUMBER_ID));
327 td.AddField("hunger", FieldDescription(((char *)&c.hunger) - ((char *)&c), Interpreter::NUMBER_ID));
329 td.AddField("healthBoost", FieldDescription(((char *)&c.healthBoost) - ((char *)&c), Interpreter::NUMBER_ID));
330 td.AddField("statBoost", FieldDescription(((char *)&c.statBoost) - ((char *)&c), Stats::TYPE_ID));
333 void Capsule::Class::Construct(void *data) {
334 new (data) Capsule::Class;