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"
19 #include <SDL_image.h>
22 using battle::Monster;
24 using graphics::Animation;
25 using graphics::ComplexAnimation;
26 using graphics::SimpleAnimation;
27 using graphics::Sprite;
28 using geometry::Vector;
37 Interpreter::~Interpreter() {
38 for (vector<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.end()); i != end; ++i) {
41 for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
44 for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
47 for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
50 for (vector<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
53 for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
56 for (vector<const char *>::const_iterator i(strings.begin()), end(strings.end()); i != end; ++i) {
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.type == COMPLEX_ANIMATION) {
66 return complexAnimations[i->second.index];
67 } else if (i->second.type == SIMPLE_ANIMATION) {
68 return simpleAnimations[i->second.index];
70 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
73 throw Error("access to undefined Animation " + name);
77 bool Interpreter::GetBoolean(const std::string &name) const {
78 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
79 if (i != parsedDefinitions.end()) {
80 if (i->second.type == BOOLEAN) {
81 return booleans[i->second.index];
83 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Boolean");
86 throw Error("access to undefined Boolean " + name);
90 Hero *Interpreter::GetHero(const std::string &name) {
91 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
92 if (i != parsedDefinitions.end()) {
93 if (i->second.type == HERO) {
94 return heroes[i->second.index];
96 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
99 throw Error("access to undefined Hero " + name);
103 Monster *Interpreter::GetMonster(const std::string &name) {
104 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
105 if (i != parsedDefinitions.end()) {
106 if (i->second.type == MONSTER) {
107 return monsters[i->second.index];
109 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
112 throw Error("access to undefined Monster " + name);
116 int Interpreter::GetNumber(const std::string &name) const {
117 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
118 if (i != parsedDefinitions.end()) {
119 if (i->second.type == NUMBER) {
120 return numbers[i->second.index];
122 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
125 throw Error("access to undefined Number " + name);
129 Sprite *Interpreter::GetSprite(const std::string &name) {
130 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
131 if (i != parsedDefinitions.end()) {
132 if (i->second.type == SPRITE) {
133 return sprites[i->second.index];
135 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
138 throw Error("access to undefined Sprite " + name);
142 const char *Interpreter::GetString(const std::string &name) const {
143 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
144 if (i != parsedDefinitions.end()) {
145 if (i->second.type == STRING) {
146 return strings[i->second.index];
148 throw Error("cannot cast " + i->second.dfn->TypeName() + " to String");
151 throw Error("access to undefined String " + name);
155 Vector<int> Interpreter::GetVector(const std::string &name) const {
156 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
157 if (i != parsedDefinitions.end()) {
158 if (i->second.type == VECTOR) {
159 return vectors[i->second.index];
161 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Vector");
164 throw Error("access to undefined Vector " + name);
169 void Interpreter::ReadSource() {
170 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
171 ReadDefinition(source.GetDefinition(*i));
175 void Interpreter::ReadDefinition(const Definition &dfn) {
176 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
179 if (dfn.HasLiteralValue()) {
186 void Interpreter::ReadLiteral(const Definition &dfn) {
187 switch (dfn.GetLiteral()->GetType()) {
188 case Literal::ARRAY_VALUES:
189 valueArrays.push_back(dfn.GetLiteral()->GetValues());
190 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VALUE_ARRAY, valueArrays.size() - 1)));
192 case Literal::ARRAY_PROPS:
193 propertyListArrays.push_back(dfn.GetLiteral()->GetPropertyLists());
194 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PROPERTY_LIST_ARRAY, propertyListArrays.size() - 1)));
196 case Literal::BOOLEAN:
197 booleans.push_back(dfn.GetLiteral()->GetBoolean());
198 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BOOLEAN, booleans.size() - 1)));
201 throw Error("unhandled literal: color");
203 case Literal::NUMBER:
204 numbers.push_back(dfn.GetLiteral()->GetNumber());
205 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
207 case Literal::STRING:
209 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
210 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
211 str[dfn.GetLiteral()->GetString().size()] = '\0';
212 strings.push_back(str);
214 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, STRING, strings.size() - 1)));
216 case Literal::VECTOR:
217 vectors.push_back(Vector<int>(dfn.GetLiteral()->GetX(), dfn.GetLiteral()->GetY()));
218 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VECTOR, vectors.size() - 1)));
220 case Literal::OBJECT:
226 Animation *Interpreter::GetAnimation(const Value &v) {
228 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
229 ComplexAnimation *a(new ComplexAnimation);
230 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
231 complexAnimations.push_back(a);
234 SimpleAnimation *a(new SimpleAnimation);
235 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
236 simpleAnimations.push_back(a);
240 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
241 return GetAnimation(v.GetIdentifier());
245 bool Interpreter::GetBoolean(const Value &v) {
247 return v.GetLiteral().GetBoolean();
249 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
250 return GetBoolean(v.GetIdentifier());
254 SDL_Surface *Interpreter::GetImage(const Value &v) {
255 const char *file(GetString(v));
256 SDL_Surface *image(IMG_Load(file));
257 images.push_back(image);
261 int Interpreter::GetNumber(const Value &v) {
263 return v.GetLiteral().GetNumber();
265 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
266 return GetNumber(v.GetIdentifier());
270 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
272 return v.GetLiteral().GetProperties();
274 throw Error("cannot reference property lists");
278 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
280 return v.GetLiteral().GetPropertyLists();
282 throw Error("cannot reference property list arrays");
286 Sprite *Interpreter::GetSprite(const Value &v) {
288 Sprite *s(new Sprite);
289 ReadSprite(*s, *v.GetLiteral().GetProperties());
292 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
293 return GetSprite(v.GetIdentifier());
297 const char *Interpreter::GetString(const Value &v) {
299 return v.GetLiteral().GetString().c_str();
301 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
302 return GetString(v.GetIdentifier());
306 Vector<int> Interpreter::GetVector(const Value &v) {
308 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
310 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
311 return GetVector(v.GetIdentifier());
315 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
317 return v.GetLiteral().GetValues();
319 throw Error("cannot reference value arrays");
324 void Interpreter::ReadObject(const Definition &dfn) {
325 if (dfn.TypeName() == "ComplexAnimation") {
326 ComplexAnimation *animation(new ComplexAnimation);
327 int index(complexAnimations.size());
328 complexAnimations.push_back(animation);
329 ReadComplexAnimation(*animation, *dfn.GetProperties());
330 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
331 } else if (dfn.TypeName() == "Hero") {
332 Hero *hero(new Hero);
333 int index(heroes.size());
334 heroes.push_back(hero);
335 ReadHero(*hero, *dfn.GetProperties());
336 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
337 } else if (dfn.TypeName() == "Monster") {
338 Monster *monster(new Monster);
339 int index(monsters.size());
340 monsters.push_back(monster);
341 ReadMonster(*monster, *dfn.GetProperties());
342 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
343 } else if (dfn.TypeName() == "SimpleAnimation") {
344 SimpleAnimation *animation(new SimpleAnimation);
345 int index(simpleAnimations.size());
346 simpleAnimations.push_back(animation);
347 ReadSimpleAnimation(*animation, *dfn.GetProperties());
348 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
349 } else if (dfn.TypeName() == "Sprite") {
350 Sprite *sprite(new Sprite);
351 int index(sprites.size());
352 sprites.push_back(sprite);
353 ReadSprite(*sprite, *dfn.GetProperties());
354 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
356 throw Error("unhandled object type: " + dfn.TypeName());
361 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
362 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
363 if (i->first == "sprite") {
364 a.SetSprite(GetSprite(*i->second));
365 } else if (i->first == "frametime") {
366 a.SetFrameTime(GetNumber(*i->second));
367 } else if (i->first == "repeat") {
368 a.SetRepeat(GetBoolean(*i->second));
369 } else if (i->first == "frames") {
370 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
371 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
372 ComplexAnimation::FrameProp frame;
373 ReadComplexAnimationFrame(frame, **i);
377 throw Error("unknown ComplexAnimation property: " + i->first);
382 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
383 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
384 if (i->first == "column") {
385 f.col = GetNumber(*i->second);
386 } else if (i->first == "row") {
387 f.row = GetNumber(*i->second);
388 } else if (i->first == "disposition") {
389 f.disposition = GetVector(*i->second);
391 throw Error("unknown ComplexAnimationFrame property: " + i->first);
396 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
397 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
398 if (i->first == "name") {
399 h.SetName(GetString(*i->second));
400 } else if (i->first == "sprite") {
401 h.SetSprite(GetSprite(*i->second));
402 } else if (i->first == "level") {
403 h.SetLevel(GetNumber(*i->second));
404 } else if (i->first == "maxHealth") {
405 h.SetMaxHealth(GetNumber(*i->second));
406 } else if (i->first == "health") {
407 h.SetHealth(GetNumber(*i->second));
408 } else if (i->first == "maxMana") {
409 h.SetMaxMana(GetNumber(*i->second));
410 } else if (i->first == "mana") {
411 h.SetMana(GetNumber(*i->second));
412 } else if (i->first == "ip") {
413 h.SetIP(GetNumber(*i->second));
414 } else if (i->first == "stats") {
416 ReadStats(stats, *GetPropertyList(*i->second));
418 } else if (i->first == "attackAnimation") {
419 h.SetAttackAnimation(GetAnimation(*i->second));
420 } else if (i->first == "spellAnimation") {
421 h.SetSpellAnimation(GetAnimation(*i->second));
422 } else if (i->first == "meleeAnimation") {
423 h.SetMeleeAnimation(GetAnimation(*i->second));
425 throw Error("unknown Hero property: " + i->first);
430 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
431 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
432 if (i->first == "name") {
433 m.SetName(GetString(*i->second));
434 } else if (i->first == "sprite") {
435 m.SetSprite(GetSprite(*i->second));
436 } else if (i->first == "level") {
437 m.SetLevel(GetNumber(*i->second));
438 } else if (i->first == "maxHealth") {
439 m.SetMaxHealth(GetNumber(*i->second));
440 } else if (i->first == "health") {
441 m.SetHealth(GetNumber(*i->second));
442 } else if (i->first == "maxMana") {
443 m.SetMaxMana(GetNumber(*i->second));
444 } else if (i->first == "mana") {
445 m.SetMana(GetNumber(*i->second));
446 } else if (i->first == "stats") {
448 ReadStats(stats, *GetPropertyList(*i->second));
450 } else if (i->first == "attackAnimation") {
451 m.SetAttackAnimation(GetAnimation(*i->second));
452 } else if (i->first == "meleeAnimation") {
453 m.SetMeleeAnimation(GetAnimation(*i->second));
455 throw Error("unknown Monster property: " + i->first);
460 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
461 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
462 if (i->first == "sprite") {
463 a.SetSprite(GetSprite(*i->second));
464 } else if (i->first == "frametime") {
465 a.SetFrameTime(GetNumber(*i->second));
466 } else if (i->first == "repeat") {
467 a.SetRepeat(GetBoolean(*i->second));
468 } else if (i->first == "framecount") {
469 a.SetNumFrames(GetNumber(*i->second));
470 } else if (i->first == "col") {
471 a.SetCol(GetNumber(*i->second));
472 } else if (i->first == "row") {
473 a.SetRow(GetNumber(*i->second));
475 throw Error("unknown SimpleAnimation property: " + i->first);
480 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
481 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
482 if (i->first == "image") {
483 s.SetSurface(GetImage(*i->second));
484 } else if (i->first == "size") {
485 s.SetSize(GetVector(*i->second));
486 } else if (i->first == "offset") {
487 s.SetOffset(GetVector(*i->second));
489 throw Error("unknown Sprite property: " + i->first);
494 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
495 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
496 if (i->first == "atp") {
497 s.SetAttack(GetNumber(*i->second));
498 } else if (i->first == "dfp") {
499 s.SetDefense(GetNumber(*i->second));
500 } else if (i->first == "str") {
501 s.SetStrength(GetNumber(*i->second));
502 } else if (i->first == "agl") {
503 s.SetAgility(GetNumber(*i->second));
504 } else if (i->first == "int") {
505 s.SetIntelligence(GetNumber(*i->second));
506 } else if (i->first == "gut") {
507 s.SetGut(GetNumber(*i->second));
508 } else if (i->first == "mgr") {
509 s.SetMagicResistance(GetNumber(*i->second));
511 throw Error("unknown Stats property: " + i->first);