]> git.localhorst.tv Git - l2e.git/blob - src/battle/Hero.cpp
reordered type description creation to avoid reallocation
[l2e.git] / src / battle / Hero.cpp
1 /*
2  * Hero.cpp
3  *
4  *  Created on: Aug 6, 2012
5  *      Author: holy
6  */
7
8 #include "Hero.h"
9
10 #include "AttackChoice.h"
11 #include "Resources.h"
12 #include "../common/Ikari.h"
13 #include "../common/Item.h"
14 #include "../common/Spell.h"
15 #include "../loader/TypeDescription.h"
16
17 using common::Ikari;
18 using common::Spell;
19 using loader::FieldDescription;
20 using loader::TypeDescription;
21 using std::vector;
22
23 namespace battle {
24
25 Hero::Hero()
26 : name("")
27 , sprite(0)
28
29 , weapon(0)
30 , armor(0)
31 , shield(0)
32 , helmet(0)
33 , ring(0)
34 , jewel(0)
35
36 , meleeAnimation(0)
37 , attackAnimation(0)
38 , spellAnimation(0)
39
40 , maxHealth(0)
41 , health(0)
42 , maxMana(0)
43 , mana(0)
44
45 , level(0)
46 , ip(0) {
47
48 }
49
50 Hero::~Hero() {
51
52 }
53
54
55 void Hero::SubtractHealth(int amount) {
56         if (amount > Health()) {
57                 health = 0;
58         } else {
59                 health -= amount;
60                 int ipGain(amount * 255 / health);
61                 if (ip + ipGain > 255) {
62                         ip = 255;
63                 } else {
64                         ip += ipGain;
65                 }
66         }
67 }
68
69
70 void Hero::UpdateSpellMenu() {
71         SpellMenu().Clear();
72         SpellMenu().Reserve(Spells().size());
73         for (vector<const Spell *>::const_iterator i(Spells().begin()), end(Spells().end()); i != end; ++i) {
74                 bool enabled((*i)->CanUseInBattle() && (*i)->Cost() <= Mana());
75                 SpellMenu().Add((*i)->Name(), *i, enabled, 0, (*i)->Cost());
76         }
77 }
78
79 void Hero::UpdateIkariMenu(const Resources *res) {
80         IkariMenu().Clear();
81         IkariMenu().Reserve(6);
82
83         if (HasWeapon()) {
84                 IkariMenu().Add(
85                                 Weapon()->Name(),
86                                 Weapon(),
87                                 Weapon()->HasIkari() && Weapon()->GetIkari()->Cost() <= IP(),
88                                 res->weaponMenuIcon,
89                                 0,
90                                 Weapon()->HasIkari() ? Weapon()->GetIkari()->Name() : "");
91         } else {
92                 IkariMenu().Add(res->noEquipmentText, 0, false, res->weaponMenuIcon);
93         }
94
95         if (HasArmor()) {
96                 IkariMenu().Add(
97                                 Armor()->Name(),
98                                 Armor(),
99                                 Armor()->HasIkari() && Armor()->GetIkari()->Cost() <= IP(),
100                                 res->armorMenuIcon,
101                                 0,
102                                 Armor()->HasIkari() ? Armor()->GetIkari()->Name() : "");
103         } else {
104                 IkariMenu().Add(res->noEquipmentText, 0, false, res->armorMenuIcon);
105         }
106
107         if (HasShield()) {
108                 IkariMenu().Add(
109                                 Shield()->Name(),
110                                 Shield(),
111                                 Shield()->HasIkari() && Shield()->GetIkari()->Cost() <= IP(),
112                                 res->shieldMenuIcon,
113                                 0,
114                                 Shield()->HasIkari() ? Shield()->GetIkari()->Name() : "");
115         } else {
116                 IkariMenu().Add(res->noEquipmentText, 0, false, res->shieldMenuIcon);
117         }
118
119         if (HasHelmet()) {
120                 IkariMenu().Add(
121                                 Helmet()->Name(),
122                                 Helmet(),
123                                 Helmet()->HasIkari() && Helmet()->GetIkari()->Cost() <= IP(),
124                                 res->helmetMenuIcon,
125                                 0,
126                                 Helmet()->HasIkari() ? Helmet()->GetIkari()->Name() : "");
127         } else {
128                 IkariMenu().Add(res->noEquipmentText, 0, false, res->helmetMenuIcon);
129         }
130
131         if (HasRing()) {
132                 IkariMenu().Add(
133                                 Ring()->Name(),
134                                 Ring(),
135                                 Ring()->HasIkari() && Ring()->GetIkari()->Cost() <= IP(),
136                                 res->ringMenuIcon,
137                                 0,
138                                 Ring()->HasIkari() ? Ring()->GetIkari()->Name() : "");
139         } else {
140                 IkariMenu().Add(res->noEquipmentText, 0, false, res->ringMenuIcon);
141         }
142
143         if (HasJewel()) {
144                 IkariMenu().Add(
145                                 Jewel()->Name(),
146                                 Jewel(),
147                                 Jewel()->HasIkari() && Jewel()->GetIkari()->Cost() <= IP(),
148                                 res->jewelMenuIcon,
149                                 0,
150                                 Jewel()->HasIkari() ? Jewel()->GetIkari()->Name() : "");
151         } else {
152                 IkariMenu().Add(res->noEquipmentText, 0, false, res->jewelMenuIcon);
153         }
154 }
155
156
157 void Hero::CreateTypeDescription() {
158         Hero h;
159
160         int animationId(TypeDescription::GetTypeId("Animation"));
161         int numberId(TypeDescription::GetTypeId("Number"));
162         int spriteId(TypeDescription::GetTypeId("Sprite"));
163         int statsId(TypeDescription::GetTypeId("Stats"));
164         int stringId(TypeDescription::GetTypeId("String"));
165
166         TypeDescription &td(TypeDescription::CreateOrGet("Hero"));
167         td.SetSize(sizeof(Hero));
168
169         td.AddField("name", FieldDescription(((char *)&h.name) - ((char *)&h), stringId, true));
170         td.AddField("sprite", FieldDescription(((char *)&h.sprite) - ((char *)&h), spriteId, true));
171         td.AddField("level", FieldDescription(((char *)&h.level) - ((char *)&h), numberId, false));
172
173         td.AddField("maxHealth", FieldDescription(((char *)&h.maxHealth) - ((char *)&h), numberId, false));
174         td.AddField("health", FieldDescription(((char *)&h.health) - ((char *)&h), numberId, false));
175         td.AddField("maxMana", FieldDescription(((char *)&h.maxMana) - ((char *)&h), numberId, false));
176         td.AddField("mana", FieldDescription(((char *)&h.mana) - ((char *)&h), numberId, false));
177         td.AddField("ip", FieldDescription(((char *)&h.ip) - ((char *)&h), numberId, false));
178         td.AddField("stats", FieldDescription(((char *)&h.stats) - ((char *)&h), statsId, false));
179
180         td.AddField("attackAnimation", FieldDescription(((char *)&h.attackAnimation) - ((char *)&h), animationId, true));
181         td.AddField("spellAnimation", FieldDescription(((char *)&h.spellAnimation) - ((char *)&h), animationId, true));
182         td.AddField("meleeAnimation", FieldDescription(((char *)&h.meleeAnimation) - ((char *)&h), animationId, true));
183 }
184
185 }