4 * Created on: Aug 26, 2012
8 #include "Interpreter.h"
10 #include "ParsedSource.h"
11 #include "../battle/Hero.h"
12 #include "../battle/Monster.h"
13 #include "../graphics/ComplexAnimation.h"
14 #include "../graphics/SimpleAnimation.h"
15 #include "../graphics/Sprite.h"
18 #include <SDL_image.h>
21 using battle::Monster;
23 using graphics::Animation;
24 using graphics::ComplexAnimation;
25 using graphics::SimpleAnimation;
26 using graphics::Sprite;
27 using geometry::Vector;
36 Interpreter::~Interpreter() {
37 for (vector<Animation *>::const_iterator i(animations.begin()), end(animations.end()); i != end; ++i) {
40 for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
43 for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
46 for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
49 for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
55 bool Interpreter::ParsedDefinition::IsCompatible(DynamicType with) const {
58 && (type == COMPLEX_ANIMATION || type == SIMPLE_ANIMATION));
62 Animation *Interpreter::GetAnimation(const std::string &name) {
63 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
64 if (i != parsedDefinitions.end()) {
65 if (i->second.IsCompatible(ANIMATION)) {
66 return animations[i->second.index];
68 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
71 throw Error("access to undefined Animation " + name);
75 Hero *Interpreter::GetHero(const std::string &name) {
76 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
77 if (i != parsedDefinitions.end()) {
78 if (i->second.IsCompatible(HERO)) {
79 return heroes[i->second.index];
81 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
84 throw Error("access to undefined Hero " + name);
88 Monster *Interpreter::GetMonster(const std::string &name) {
89 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
90 if (i != parsedDefinitions.end()) {
91 if (i->second.IsCompatible(MONSTER)) {
92 return monsters[i->second.index];
94 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
97 throw Error("access to undefined Monster " + name);
101 int Interpreter::GetNumber(const std::string &name) const {
102 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
103 if (i != parsedDefinitions.end()) {
104 if (i->second.IsCompatible(NUMBER)) {
105 return numbers[i->second.index];
107 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
110 throw Error("access to undefined Number " + name);
114 Sprite *Interpreter::GetSprite(const std::string &name) {
115 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
116 if (i != parsedDefinitions.end()) {
117 if (i->second.IsCompatible(SPRITE)) {
118 return sprites[i->second.index];
120 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
123 throw Error("access to undefined Sprite " + name);
128 void Interpreter::ReadSource() {
129 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
130 ReadDefinition(source.GetDefinition(*i));
134 void Interpreter::ReadDefinition(const Definition &dfn) {
135 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
138 if (dfn.HasLiteralValue()) {
145 void Interpreter::ReadLiteral(const Definition &dfn) {
146 switch (dfn.GetLiteral()->GetType()) {
147 case Literal::ARRAY_VALUES:
148 throw Error("unhandled literal: array of values");
150 case Literal::ARRAY_PROPS:
151 throw Error("unhandled literal: array of properties");
153 case Literal::BOOLEAN:
154 throw Error("unhandled literal: boolean");
157 throw Error("unhandled literal: color");
159 case Literal::NUMBER:
160 numbers.push_back(dfn.GetLiteral()->GetNumber());
161 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
163 case Literal::STRING:
164 throw Error("unhandled literal: string");
166 case Literal::VECTOR:
167 throw Error("unhandled literal: vector");
169 case Literal::OBJECT:
170 throw Error("unhandled literal: object");
175 Animation *Interpreter::GetAnimation(const Value &v) {
177 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
178 ComplexAnimation *a(new ComplexAnimation);
179 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
180 animations.push_back(a);
183 SimpleAnimation *a(new SimpleAnimation);
184 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
185 animations.push_back(a);
189 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
190 return GetAnimation(v.GetIdentifier());
194 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
196 return v.GetLiteral().GetValues();
198 throw Error("identifier resolution not implemented for arrays of values");
202 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
204 return v.GetLiteral().GetPropertyLists();
206 throw Error("identifier resolution not implemented for arrays of property lists");
210 bool Interpreter::GetBoolean(const Value &v) {
212 return v.GetLiteral().GetBoolean();
214 throw Error("identifier resolution not implemented for booleans");
218 SDL_Surface *Interpreter::GetImage(const Value &v) {
219 const char *file(GetString(v));
220 SDL_Surface *image(IMG_Load(file));
221 images.push_back(image);
225 int Interpreter::GetNumber(const Value &v) {
227 return v.GetLiteral().GetNumber();
229 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
230 return GetNumber(v.GetIdentifier());
234 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
236 return v.GetLiteral().GetProperties();
238 throw Error("identifier resolution not implemented for property lists");
242 Sprite *Interpreter::GetSprite(const Value &v) {
244 Sprite *s(new Sprite);
245 ReadSprite(*s, *v.GetLiteral().GetProperties());
248 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
249 return GetSprite(v.GetIdentifier());
253 const char *Interpreter::GetString(const Value &v) {
255 return v.GetLiteral().GetString().c_str();
257 throw Error("identifier resolution not implemented for strings");
261 Vector<int> Interpreter::GetVector(const Value &v) {
263 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
265 throw Error("identifier resolution not implemented for vectors");
270 void Interpreter::ReadObject(const Definition &dfn) {
271 if (dfn.TypeName() == "Hero") {
272 Hero *hero(new Hero);
273 int index(heroes.size());
274 heroes.push_back(hero);
275 ReadHero(*hero, *dfn.GetProperties());
276 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
277 } else if (dfn.TypeName() == "Monster") {
278 Monster *monster(new Monster);
279 int index(monsters.size());
280 monsters.push_back(monster);
281 ReadMonster(*monster, *dfn.GetProperties());
282 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
283 } else if (dfn.TypeName() == "Sprite") {
284 Sprite *sprite(new Sprite);
285 int index(sprites.size());
286 sprites.push_back(sprite);
287 ReadSprite(*sprite, *dfn.GetProperties());
288 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
290 throw Error("unhandled object type: " + dfn.TypeName());
295 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
296 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
297 if (i->first == "sprite") {
298 a.SetSprite(GetSprite(*i->second));
299 } else if (i->first == "frametime") {
300 a.SetFrameTime(GetNumber(*i->second));
301 } else if (i->first == "repeat") {
302 a.SetRepeat(GetBoolean(*i->second));
303 } else if (i->first == "frames") {
304 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
305 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
306 ComplexAnimation::FrameProp frame;
307 ReadComplexAnimationFrame(frame, **i);
311 throw Error("unknown ComplexAnimation property: " + i->first);
316 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
317 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
318 if (i->first == "column") {
319 f.col = GetNumber(*i->second);
320 } else if (i->first == "row") {
321 f.row = GetNumber(*i->second);
322 } else if (i->first == "disposition") {
323 f.disposition = GetVector(*i->second);
325 throw Error("unknown ComplexAnimationFrame property: " + i->first);
330 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
331 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
332 if (i->first == "name") {
333 h.SetName(GetString(*i->second));
334 } else if (i->first == "sprite") {
335 h.SetSprite(GetSprite(*i->second));
336 } else if (i->first == "level") {
337 h.SetLevel(GetNumber(*i->second));
338 } else if (i->first == "maxHealth") {
339 h.SetMaxHealth(GetNumber(*i->second));
340 } else if (i->first == "health") {
341 h.SetHealth(GetNumber(*i->second));
342 } else if (i->first == "maxMana") {
343 h.SetMaxMana(GetNumber(*i->second));
344 } else if (i->first == "mana") {
345 h.SetMana(GetNumber(*i->second));
346 } else if (i->first == "ip") {
347 h.SetIP(GetNumber(*i->second));
348 } else if (i->first == "stats") {
350 ReadStats(stats, *GetPropertyList(*i->second));
352 } else if (i->first == "attackAnimation") {
353 h.SetAttackAnimation(GetAnimation(*i->second));
354 } else if (i->first == "spellAnimation") {
355 h.SetSpellAnimation(GetAnimation(*i->second));
356 } else if (i->first == "meleeAnimation") {
357 h.SetMeleeAnimation(GetAnimation(*i->second));
359 throw Error("unknown Hero property: " + i->first);
364 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
365 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
366 if (i->first == "name") {
367 m.SetName(GetString(*i->second));
368 } else if (i->first == "sprite") {
369 m.SetSprite(GetSprite(*i->second));
370 } else if (i->first == "level") {
371 m.SetLevel(GetNumber(*i->second));
372 } else if (i->first == "maxHealth") {
373 m.SetMaxHealth(GetNumber(*i->second));
374 } else if (i->first == "health") {
375 m.SetHealth(GetNumber(*i->second));
376 } else if (i->first == "maxMana") {
377 m.SetMaxMana(GetNumber(*i->second));
378 } else if (i->first == "mana") {
379 m.SetMana(GetNumber(*i->second));
380 } else if (i->first == "stats") {
382 ReadStats(stats, *GetPropertyList(*i->second));
384 } else if (i->first == "attackAnimation") {
385 m.SetAttackAnimation(GetAnimation(*i->second));
386 } else if (i->first == "meleeAnimation") {
387 m.SetMeleeAnimation(GetAnimation(*i->second));
389 throw Error("unknown Monster property: " + i->first);
394 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
395 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
396 if (i->first == "sprite") {
397 a.SetSprite(GetSprite(*i->second));
398 } else if (i->first == "frametime") {
399 a.SetFrameTime(GetNumber(*i->second));
400 } else if (i->first == "repeat") {
401 a.SetRepeat(GetBoolean(*i->second));
402 } else if (i->first == "framecount") {
403 a.SetNumFrames(GetNumber(*i->second));
404 } else if (i->first == "col") {
405 a.SetCol(GetNumber(*i->second));
406 } else if (i->first == "row") {
407 a.SetRow(GetNumber(*i->second));
409 throw Error("unknown SimpleAnimation property: " + i->first);
414 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
415 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
416 if (i->first == "image") {
417 s.SetSurface(GetImage(*i->second));
418 } else if (i->first == "size") {
419 s.SetSize(GetVector(*i->second));
420 } else if (i->first == "offset") {
421 s.SetOffset(GetVector(*i->second));
423 throw Error("unknown Sprite property: " + i->first);
428 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
429 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
430 if (i->first == "atp") {
431 s.SetAttack(GetNumber(*i->second));
432 } else if (i->first == "dfp") {
433 s.SetDefense(GetNumber(*i->second));
434 } else if (i->first == "str") {
435 s.SetStrength(GetNumber(*i->second));
436 } else if (i->first == "agl") {
437 s.SetAgility(GetNumber(*i->second));
438 } else if (i->first == "int") {
439 s.SetIntelligence(GetNumber(*i->second));
440 } else if (i->first == "gut") {
441 s.SetGut(GetNumber(*i->second));
442 } else if (i->first == "mgr") {
443 s.SetMagicResistance(GetNumber(*i->second));
445 throw Error("unknown Stats property: " + i->first);