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 "../battle/PartyLayout.h"
14 #include "../graphics/ComplexAnimation.h"
15 #include "../graphics/SimpleAnimation.h"
16 #include "../graphics/Sprite.h"
20 #include <SDL_image.h>
23 using battle::Monster;
24 using battle::PartyLayout;
26 using graphics::Animation;
27 using graphics::ComplexAnimation;
28 using graphics::SimpleAnimation;
29 using graphics::Sprite;
30 using geometry::Vector;
39 Interpreter::~Interpreter() {
40 for (vector<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.end()); i != end; ++i) {
43 for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
46 for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
49 for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
52 for (vector<PartyLayout *>::const_iterator i(partyLayouts.begin()), end(partyLayouts.end()); i != end; ++i) {
55 for (vector<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
58 for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
61 for (vector<const char *>::const_iterator i(strings.begin()), end(strings.end()); i != end; ++i) {
67 Animation *Interpreter::GetAnimation(const std::string &name) {
68 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
69 if (i != parsedDefinitions.end()) {
70 if (i->second.type == COMPLEX_ANIMATION) {
71 return complexAnimations[i->second.index];
72 } else if (i->second.type == SIMPLE_ANIMATION) {
73 return simpleAnimations[i->second.index];
75 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
78 throw Error("access to undefined Animation " + name);
82 bool Interpreter::GetBoolean(const std::string &name) const {
83 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
84 if (i != parsedDefinitions.end()) {
85 if (i->second.type == BOOLEAN) {
86 return booleans[i->second.index];
88 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Boolean");
91 throw Error("access to undefined Boolean " + name);
95 Hero *Interpreter::GetHero(const std::string &name) {
96 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
97 if (i != parsedDefinitions.end()) {
98 if (i->second.type == HERO) {
99 return heroes[i->second.index];
101 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
104 throw Error("access to undefined Hero " + name);
108 Monster *Interpreter::GetMonster(const std::string &name) {
109 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
110 if (i != parsedDefinitions.end()) {
111 if (i->second.type == MONSTER) {
112 return monsters[i->second.index];
114 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
117 throw Error("access to undefined Monster " + name);
121 int Interpreter::GetNumber(const std::string &name) const {
122 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
123 if (i != parsedDefinitions.end()) {
124 if (i->second.type == NUMBER) {
125 return numbers[i->second.index];
127 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
130 throw Error("access to undefined Number " + name);
134 PartyLayout *Interpreter::GetPartyLayout(const std::string &name) {
135 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
136 if (i != parsedDefinitions.end()) {
137 if (i->second.type == PARTY_LAYOUT) {
138 return partyLayouts[i->second.index];
140 throw Error("cannot cast " + i->second.dfn->TypeName() + " to PartyLayout");
143 throw Error("access to undefined PartyLayout " + name);
147 Sprite *Interpreter::GetSprite(const std::string &name) {
148 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
149 if (i != parsedDefinitions.end()) {
150 if (i->second.type == SPRITE) {
151 return sprites[i->second.index];
153 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
156 throw Error("access to undefined Sprite " + name);
160 const char *Interpreter::GetString(const std::string &name) const {
161 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
162 if (i != parsedDefinitions.end()) {
163 if (i->second.type == STRING) {
164 return strings[i->second.index];
166 throw Error("cannot cast " + i->second.dfn->TypeName() + " to String");
169 throw Error("access to undefined String " + name);
173 Vector<int> Interpreter::GetVector(const std::string &name) const {
174 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
175 if (i != parsedDefinitions.end()) {
176 if (i->second.type == VECTOR) {
177 return vectors[i->second.index];
179 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Vector");
182 throw Error("access to undefined Vector " + name);
187 void Interpreter::ReadSource() {
188 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
189 ReadDefinition(source.GetDefinition(*i));
193 void Interpreter::ReadDefinition(const Definition &dfn) {
194 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
197 if (dfn.HasLiteralValue()) {
204 void Interpreter::ReadLiteral(const Definition &dfn) {
205 switch (dfn.GetLiteral()->GetType()) {
206 case Literal::ARRAY_VALUES:
207 valueArrays.push_back(dfn.GetLiteral()->GetValues());
208 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VALUE_ARRAY, valueArrays.size() - 1)));
210 case Literal::ARRAY_PROPS:
211 propertyListArrays.push_back(dfn.GetLiteral()->GetPropertyLists());
212 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PROPERTY_LIST_ARRAY, propertyListArrays.size() - 1)));
214 case Literal::BOOLEAN:
215 booleans.push_back(dfn.GetLiteral()->GetBoolean());
216 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BOOLEAN, booleans.size() - 1)));
219 throw Error("unhandled literal: color");
221 case Literal::NUMBER:
222 numbers.push_back(dfn.GetLiteral()->GetNumber());
223 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
225 case Literal::STRING:
227 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
228 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
229 str[dfn.GetLiteral()->GetString().size()] = '\0';
230 strings.push_back(str);
232 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, STRING, strings.size() - 1)));
234 case Literal::VECTOR:
235 vectors.push_back(Vector<int>(dfn.GetLiteral()->GetX(), dfn.GetLiteral()->GetY()));
236 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VECTOR, vectors.size() - 1)));
238 case Literal::OBJECT:
244 Animation *Interpreter::GetAnimation(const Value &v) {
246 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
247 ComplexAnimation *a(new ComplexAnimation);
248 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
249 complexAnimations.push_back(a);
252 SimpleAnimation *a(new SimpleAnimation);
253 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
254 simpleAnimations.push_back(a);
258 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
259 return GetAnimation(v.GetIdentifier());
263 bool Interpreter::GetBoolean(const Value &v) {
265 return v.GetLiteral().GetBoolean();
267 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
268 return GetBoolean(v.GetIdentifier());
272 SDL_Surface *Interpreter::GetImage(const Value &v) {
273 const char *file(GetString(v));
274 SDL_Surface *image(IMG_Load(file));
275 images.push_back(image);
279 int Interpreter::GetNumber(const Value &v) {
281 return v.GetLiteral().GetNumber();
283 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
284 return GetNumber(v.GetIdentifier());
288 PartyLayout *Interpreter::GetPartyLayout(const Value &v) {
290 PartyLayout *l(new PartyLayout);
291 ReadPartyLayout(*l, *v.GetLiteral().GetProperties());
294 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
295 return GetPartyLayout(v.GetIdentifier());
299 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
301 return v.GetLiteral().GetProperties();
303 throw Error("cannot reference property lists");
307 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
309 return v.GetLiteral().GetPropertyLists();
311 throw Error("cannot reference property list arrays");
315 Sprite *Interpreter::GetSprite(const Value &v) {
317 Sprite *s(new Sprite);
318 ReadSprite(*s, *v.GetLiteral().GetProperties());
321 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
322 return GetSprite(v.GetIdentifier());
326 const char *Interpreter::GetString(const Value &v) {
328 return v.GetLiteral().GetString().c_str();
330 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
331 return GetString(v.GetIdentifier());
335 Vector<int> Interpreter::GetVector(const Value &v) {
337 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
339 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
340 return GetVector(v.GetIdentifier());
344 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
346 return v.GetLiteral().GetValues();
348 throw Error("cannot reference value arrays");
353 void Interpreter::ReadObject(const Definition &dfn) {
354 if (dfn.TypeName() == "ComplexAnimation") {
355 ComplexAnimation *animation(new ComplexAnimation);
356 int index(complexAnimations.size());
357 complexAnimations.push_back(animation);
358 ReadComplexAnimation(*animation, *dfn.GetProperties());
359 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
360 } else if (dfn.TypeName() == "Hero") {
361 Hero *hero(new Hero);
362 int index(heroes.size());
363 heroes.push_back(hero);
364 ReadHero(*hero, *dfn.GetProperties());
365 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
366 } else if (dfn.TypeName() == "Monster") {
367 Monster *monster(new Monster);
368 int index(monsters.size());
369 monsters.push_back(monster);
370 ReadMonster(*monster, *dfn.GetProperties());
371 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
372 } else if (dfn.TypeName() == "PartyLayout") {
373 PartyLayout *layout(new PartyLayout);
374 int index(partyLayouts.size());
375 partyLayouts.push_back(layout);
376 ReadPartyLayout(*layout, *dfn.GetProperties());
377 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PARTY_LAYOUT, index)));
378 } else if (dfn.TypeName() == "SimpleAnimation") {
379 SimpleAnimation *animation(new SimpleAnimation);
380 int index(simpleAnimations.size());
381 simpleAnimations.push_back(animation);
382 ReadSimpleAnimation(*animation, *dfn.GetProperties());
383 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
384 } else if (dfn.TypeName() == "Sprite") {
385 Sprite *sprite(new Sprite);
386 int index(sprites.size());
387 sprites.push_back(sprite);
388 ReadSprite(*sprite, *dfn.GetProperties());
389 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
391 throw Error("unhandled object type: " + dfn.TypeName());
396 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
397 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
398 if (i->first == "sprite") {
399 a.SetSprite(GetSprite(*i->second));
400 } else if (i->first == "frametime") {
401 a.SetFrameTime(GetNumber(*i->second));
402 } else if (i->first == "repeat") {
403 a.SetRepeat(GetBoolean(*i->second));
404 } else if (i->first == "frames") {
405 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
406 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
407 ComplexAnimation::FrameProp frame;
408 ReadComplexAnimationFrame(frame, **i);
412 throw Error("unknown ComplexAnimation property: " + i->first);
417 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
418 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
419 if (i->first == "column") {
420 f.col = GetNumber(*i->second);
421 } else if (i->first == "row") {
422 f.row = GetNumber(*i->second);
423 } else if (i->first == "disposition") {
424 f.disposition = GetVector(*i->second);
426 throw Error("unknown ComplexAnimationFrame property: " + i->first);
431 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
432 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
433 if (i->first == "name") {
434 h.SetName(GetString(*i->second));
435 } else if (i->first == "sprite") {
436 h.SetSprite(GetSprite(*i->second));
437 } else if (i->first == "level") {
438 h.SetLevel(GetNumber(*i->second));
439 } else if (i->first == "maxHealth") {
440 h.SetMaxHealth(GetNumber(*i->second));
441 } else if (i->first == "health") {
442 h.SetHealth(GetNumber(*i->second));
443 } else if (i->first == "maxMana") {
444 h.SetMaxMana(GetNumber(*i->second));
445 } else if (i->first == "mana") {
446 h.SetMana(GetNumber(*i->second));
447 } else if (i->first == "ip") {
448 h.SetIP(GetNumber(*i->second));
449 } else if (i->first == "stats") {
451 ReadStats(stats, *GetPropertyList(*i->second));
453 } else if (i->first == "attackAnimation") {
454 h.SetAttackAnimation(GetAnimation(*i->second));
455 } else if (i->first == "spellAnimation") {
456 h.SetSpellAnimation(GetAnimation(*i->second));
457 } else if (i->first == "meleeAnimation") {
458 h.SetMeleeAnimation(GetAnimation(*i->second));
460 throw Error("unknown Hero property: " + i->first);
465 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
466 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
467 if (i->first == "name") {
468 m.SetName(GetString(*i->second));
469 } else if (i->first == "sprite") {
470 m.SetSprite(GetSprite(*i->second));
471 } else if (i->first == "level") {
472 m.SetLevel(GetNumber(*i->second));
473 } else if (i->first == "maxHealth") {
474 m.SetMaxHealth(GetNumber(*i->second));
475 } else if (i->first == "health") {
476 m.SetHealth(GetNumber(*i->second));
477 } else if (i->first == "maxMana") {
478 m.SetMaxMana(GetNumber(*i->second));
479 } else if (i->first == "mana") {
480 m.SetMana(GetNumber(*i->second));
481 } else if (i->first == "stats") {
483 ReadStats(stats, *GetPropertyList(*i->second));
485 } else if (i->first == "attackAnimation") {
486 m.SetAttackAnimation(GetAnimation(*i->second));
487 } else if (i->first == "meleeAnimation") {
488 m.SetMeleeAnimation(GetAnimation(*i->second));
490 throw Error("unknown Monster property: " + i->first);
495 void Interpreter::ReadPartyLayout(PartyLayout &p, const PropertyList &props) {
496 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
497 if (i->first == "positions") {
498 const vector<Value *> &positions(GetValueArray(*i->second));
499 for (vector<Value *>::const_iterator j(positions.begin()), end(positions.end()); j != end; ++j) {
500 p.AddPosition(GetVector(**j));
503 throw Error("unknown PartyLayout property: " + i->first);
508 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
509 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
510 if (i->first == "sprite") {
511 a.SetSprite(GetSprite(*i->second));
512 } else if (i->first == "frametime") {
513 a.SetFrameTime(GetNumber(*i->second));
514 } else if (i->first == "repeat") {
515 a.SetRepeat(GetBoolean(*i->second));
516 } else if (i->first == "framecount") {
517 a.SetNumFrames(GetNumber(*i->second));
518 } else if (i->first == "col") {
519 a.SetCol(GetNumber(*i->second));
520 } else if (i->first == "row") {
521 a.SetRow(GetNumber(*i->second));
523 throw Error("unknown SimpleAnimation property: " + i->first);
528 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
529 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
530 if (i->first == "image") {
531 s.SetSurface(GetImage(*i->second));
532 } else if (i->first == "size") {
533 s.SetSize(GetVector(*i->second));
534 } else if (i->first == "offset") {
535 s.SetOffset(GetVector(*i->second));
537 throw Error("unknown Sprite property: " + i->first);
542 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
543 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
544 if (i->first == "atp") {
545 s.SetAttack(GetNumber(*i->second));
546 } else if (i->first == "dfp") {
547 s.SetDefense(GetNumber(*i->second));
548 } else if (i->first == "str") {
549 s.SetStrength(GetNumber(*i->second));
550 } else if (i->first == "agl") {
551 s.SetAgility(GetNumber(*i->second));
552 } else if (i->first == "int") {
553 s.SetIntelligence(GetNumber(*i->second));
554 } else if (i->first == "gut") {
555 s.SetGut(GetNumber(*i->second));
556 } else if (i->first == "mgr") {
557 s.SetMagicResistance(GetNumber(*i->second));
559 throw Error("unknown Stats property: " + i->first);