3 #include "../common/Item.h"
4 #include "../common/Spell.h"
5 #include "../common/Stats.h"
6 #include "../graphics/Animation.h"
7 #include "../graphics/Sprite.h"
8 #include "../loader/Interpreter.h"
9 #include "../loader/TypeDescription.h"
15 using graphics::Animation;
16 using graphics::Sprite;
17 using loader::FieldDescription;
18 using loader::Interpreter;
19 using loader::TypeDescription;
46 const char *Capsule::ClassName() const {
47 return GetClass().name;
50 const char *Capsule::Tribe() const {
51 return GetClass().tribe;
54 const Spell *Capsule::Attack1() const {
55 return GetClass().attacks[0];
58 const Spell *Capsule::Attack2() const {
59 return GetClass().attacks[1];
62 const Spell *Capsule::Attack3() const {
63 return GetClass().attacks[2];
67 Uint16 Capsule::MaxHealth() const {
68 return maxHealth + GetClass().healthBoost;
72 Stats Capsule::GetStats() const {
73 return stats + GetClass().statBoost;
76 int Capsule::NextLevel() const {
77 int levelOffset(Level() - 1);
78 if (levelOffset < numLevels) {
79 return levelLadder[levelOffset] - Experience();
85 void Capsule::AddExperience(int exp, vector<Hero::UpgradeInfo> &info) {
86 if (level > numLevels) {
87 // don't award any experience if at highest level
91 while (remain >= NextLevel()) {
92 int added = NextLevel();
97 info.push_back(Hero::UpgradeInfo(Hero::UPGRADE_LVL, level));
99 // TODO: upgrade attributes and push info
101 if (level > numLevels) {
105 experience += remain;
109 void Capsule::UpgradeClass() {
114 void Capsule::NextClass() {
115 if (maxClass == numClasses) {
119 if (curClass >= maxClass) {
124 void Capsule::PreviousClass() {
125 if (maxClass == numClasses) {
130 curClass = maxClass - 1;
134 void Capsule::SetClass(int index) {
135 if (maxClass == numClasses) {
142 if (curClass >= maxClass) {
143 curClass = maxClass - 1;
148 Sprite *Capsule::BattleSprite() {
149 return GetClass().battleSprite;
152 const Sprite *Capsule::BattleSprite() const {
153 return GetClass().battleSprite;
156 Animation *Capsule::MeleeAnimation() {
157 return GetClass().meleeAnimation;
160 Animation *Capsule::AttackAnimation() {
161 return GetClass().attackAnimation;
164 Animation *Capsule::SpellAnimation() {
165 return GetClass().spellAnimation;
169 Capsule::Class &Capsule::GetClass() {
170 assert(classes && curClass < numClasses);
171 return classes[curClass];
174 const Capsule::Class &Capsule::GetClass() const {
175 assert(classes && curClass < numClasses);
176 return classes[curClass];
180 int Capsule::HungerEmpty() const {
181 return HungerTotal() - HungerFull();
184 int Capsule::HungerTotal() const {
185 return GetClass().hunger;
188 int Capsule::HungerFull() const {
189 return GetClass().hungerFull;
192 bool Capsule::IsHungry() const {
193 return HungerEmpty();
196 void Capsule::Feed(const common::Item *item) {
197 // TODO: find out how to calculate an item's feed value
198 // TODO: an item the capsule favors (changes on every feed and after every
199 // battle) doubles the value
201 GetClass().hungerFull += value;
202 if (GetClass().hungerFull >= GetClass().hunger) {
203 GetClass().hungerFull = GetClass().hunger;
208 const common::Item *Capsule::UpgradeItem() const {
209 return GetClass().upgradeItem;
212 void Capsule::UpgradeSpecial() {
213 maxClass = GetClass().upgradeClass + 1;
214 curClass = GetClass().upgradeClass;
218 Capsule::Class::Class()
239 void Capsule::CreateTypeDescription() {
242 TypeDescription &td(TypeDescription::Create(TYPE_ID, "Capsule"));
243 td.SetConstructor(&Construct);
244 td.SetSize(sizeof(Capsule));
246 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
247 td.AddField("alignment", FieldDescription(((char *)&c.alignment) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
249 td.AddField("alignmentCursor", FieldDescription(((char *)&c.alignmentCursor) - ((char *)&c), Interpreter::VECTOR_ID));
250 td.AddField("alignmentSprite", FieldDescription(((char *)&c.alignmentSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
252 td.AddField("maxHealth", FieldDescription(((char *)&c.maxHealth) - ((char *)&c), Interpreter::NUMBER_ID));
254 td.AddField("stats", FieldDescription(((char *)&c.stats) - ((char *)&c), Stats::TYPE_ID));
256 td.AddField("level", FieldDescription(((char *)&c.level) - ((char *)&c), Interpreter::NUMBER_ID));
257 td.AddField("experience", FieldDescription(((char *)&c.experience) - ((char *)&c), Interpreter::NUMBER_ID));
259 td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), Interpreter::NUMBER_ID).SetAggregate());
261 td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetAggregate());
262 td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID));
263 td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID));
265 Class::CreateTypeDescription();
268 void Capsule::Construct(void *data) {
273 void Capsule::Class::CreateTypeDescription() {
276 TypeDescription &td(TypeDescription::Create(TYPE_ID, "CapsuleClass"));
277 td.SetConstructor(&Construct);
278 td.SetSize(sizeof(Class));
280 td.AddField("name", FieldDescription(((char *)&c.name) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
281 td.AddField("tribe", FieldDescription(((char *)&c.tribe) - ((char *)&c), Interpreter::STRING_ID).SetReferenced());
283 td.AddField("attack1", FieldDescription(((char *)&c.attacks[0]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
284 td.AddField("attack2", FieldDescription(((char *)&c.attacks[1]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
285 td.AddField("attack3", FieldDescription(((char *)&c.attacks[2]) - ((char *)&c), Spell::TYPE_ID).SetReferenced());
287 td.AddField("battleSprite", FieldDescription(((char *)&c.battleSprite) - ((char *)&c), Sprite::TYPE_ID).SetReferenced());
288 td.AddField("meleeAnimation", FieldDescription(((char *)&c.meleeAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
289 td.AddField("attackAnimation", FieldDescription(((char *)&c.attackAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
290 td.AddField("spellAnimation", FieldDescription(((char *)&c.spellAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
292 td.AddField("upgradeItem", FieldDescription(((char *)&c.upgradeItem) - ((char *)&c), common::Item::TYPE_ID).SetReferenced());
293 td.AddField("upgradeClass", FieldDescription(((char *)&c.upgradeClass) - ((char *)&c), Interpreter::NUMBER_ID));
294 td.AddField("hunger", FieldDescription(((char *)&c.hunger) - ((char *)&c), Interpreter::NUMBER_ID));
296 td.AddField("healthBoost", FieldDescription(((char *)&c.healthBoost) - ((char *)&c), Interpreter::NUMBER_ID));
297 td.AddField("statBoost", FieldDescription(((char *)&c.statBoost) - ((char *)&c), Stats::TYPE_ID));
300 void Capsule::Class::Construct(void *data) {
301 new (data) Capsule::Class;