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<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.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<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
52 for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
58 Animation *Interpreter::GetAnimation(const std::string &name) {
59 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
60 if (i != parsedDefinitions.end()) {
61 if (i->second.type == COMPLEX_ANIMATION) {
62 return complexAnimations[i->second.index];
63 } else if (i->second.type == SIMPLE_ANIMATION) {
64 return simpleAnimations[i->second.index];
66 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
69 throw Error("access to undefined Animation " + name);
73 Hero *Interpreter::GetHero(const std::string &name) {
74 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
75 if (i != parsedDefinitions.end()) {
76 if (i->second.type == HERO) {
77 return heroes[i->second.index];
79 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
82 throw Error("access to undefined Hero " + name);
86 Monster *Interpreter::GetMonster(const std::string &name) {
87 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
88 if (i != parsedDefinitions.end()) {
89 if (i->second.type == MONSTER) {
90 return monsters[i->second.index];
92 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
95 throw Error("access to undefined Monster " + name);
99 int Interpreter::GetNumber(const std::string &name) const {
100 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
101 if (i != parsedDefinitions.end()) {
102 if (i->second.type == NUMBER) {
103 return numbers[i->second.index];
105 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
108 throw Error("access to undefined Number " + name);
112 Sprite *Interpreter::GetSprite(const std::string &name) {
113 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
114 if (i != parsedDefinitions.end()) {
115 if (i->second.type == SPRITE) {
116 return sprites[i->second.index];
118 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
121 throw Error("access to undefined Sprite " + name);
126 void Interpreter::ReadSource() {
127 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
128 ReadDefinition(source.GetDefinition(*i));
132 void Interpreter::ReadDefinition(const Definition &dfn) {
133 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
136 if (dfn.HasLiteralValue()) {
143 void Interpreter::ReadLiteral(const Definition &dfn) {
144 switch (dfn.GetLiteral()->GetType()) {
145 case Literal::ARRAY_VALUES:
146 throw Error("unhandled literal: array of values");
148 case Literal::ARRAY_PROPS:
149 throw Error("unhandled literal: array of properties");
151 case Literal::BOOLEAN:
152 throw Error("unhandled literal: boolean");
155 throw Error("unhandled literal: color");
157 case Literal::NUMBER:
158 numbers.push_back(dfn.GetLiteral()->GetNumber());
159 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
161 case Literal::STRING:
162 throw Error("unhandled literal: string");
164 case Literal::VECTOR:
165 throw Error("unhandled literal: vector");
167 case Literal::OBJECT:
168 throw Error("unhandled literal: object");
173 Animation *Interpreter::GetAnimation(const Value &v) {
175 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
176 ComplexAnimation *a(new ComplexAnimation);
177 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
178 complexAnimations.push_back(a);
181 SimpleAnimation *a(new SimpleAnimation);
182 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
183 simpleAnimations.push_back(a);
187 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
188 return GetAnimation(v.GetIdentifier());
192 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
194 return v.GetLiteral().GetValues();
196 throw Error("identifier resolution not implemented for arrays of values");
200 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
202 return v.GetLiteral().GetPropertyLists();
204 throw Error("identifier resolution not implemented for arrays of property lists");
208 bool Interpreter::GetBoolean(const Value &v) {
210 return v.GetLiteral().GetBoolean();
212 throw Error("identifier resolution not implemented for booleans");
216 SDL_Surface *Interpreter::GetImage(const Value &v) {
217 const char *file(GetString(v));
218 SDL_Surface *image(IMG_Load(file));
219 images.push_back(image);
223 int Interpreter::GetNumber(const Value &v) {
225 return v.GetLiteral().GetNumber();
227 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
228 return GetNumber(v.GetIdentifier());
232 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
234 return v.GetLiteral().GetProperties();
236 throw Error("identifier resolution not implemented for property lists");
240 Sprite *Interpreter::GetSprite(const Value &v) {
242 Sprite *s(new Sprite);
243 ReadSprite(*s, *v.GetLiteral().GetProperties());
246 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
247 return GetSprite(v.GetIdentifier());
251 const char *Interpreter::GetString(const Value &v) {
253 return v.GetLiteral().GetString().c_str();
255 throw Error("identifier resolution not implemented for strings");
259 Vector<int> Interpreter::GetVector(const Value &v) {
261 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
263 throw Error("identifier resolution not implemented for vectors");
268 void Interpreter::ReadObject(const Definition &dfn) {
269 if (dfn.TypeName() == "ComplexAnimation") {
270 ComplexAnimation *animation(new ComplexAnimation);
271 int index(complexAnimations.size());
272 complexAnimations.push_back(animation);
273 ReadComplexAnimation(*animation, *dfn.GetProperties());
274 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
275 } else if (dfn.TypeName() == "Hero") {
276 Hero *hero(new Hero);
277 int index(heroes.size());
278 heroes.push_back(hero);
279 ReadHero(*hero, *dfn.GetProperties());
280 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
281 } else if (dfn.TypeName() == "Monster") {
282 Monster *monster(new Monster);
283 int index(monsters.size());
284 monsters.push_back(monster);
285 ReadMonster(*monster, *dfn.GetProperties());
286 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
287 } else if (dfn.TypeName() == "SimpleAnimation") {
288 SimpleAnimation *animation(new SimpleAnimation);
289 int index(simpleAnimations.size());
290 simpleAnimations.push_back(animation);
291 ReadSimpleAnimation(*animation, *dfn.GetProperties());
292 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
293 } else if (dfn.TypeName() == "Sprite") {
294 Sprite *sprite(new Sprite);
295 int index(sprites.size());
296 sprites.push_back(sprite);
297 ReadSprite(*sprite, *dfn.GetProperties());
298 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
300 throw Error("unhandled object type: " + dfn.TypeName());
305 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
306 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
307 if (i->first == "sprite") {
308 a.SetSprite(GetSprite(*i->second));
309 } else if (i->first == "frametime") {
310 a.SetFrameTime(GetNumber(*i->second));
311 } else if (i->first == "repeat") {
312 a.SetRepeat(GetBoolean(*i->second));
313 } else if (i->first == "frames") {
314 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
315 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
316 ComplexAnimation::FrameProp frame;
317 ReadComplexAnimationFrame(frame, **i);
321 throw Error("unknown ComplexAnimation property: " + i->first);
326 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
327 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
328 if (i->first == "column") {
329 f.col = GetNumber(*i->second);
330 } else if (i->first == "row") {
331 f.row = GetNumber(*i->second);
332 } else if (i->first == "disposition") {
333 f.disposition = GetVector(*i->second);
335 throw Error("unknown ComplexAnimationFrame property: " + i->first);
340 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
341 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
342 if (i->first == "name") {
343 h.SetName(GetString(*i->second));
344 } else if (i->first == "sprite") {
345 h.SetSprite(GetSprite(*i->second));
346 } else if (i->first == "level") {
347 h.SetLevel(GetNumber(*i->second));
348 } else if (i->first == "maxHealth") {
349 h.SetMaxHealth(GetNumber(*i->second));
350 } else if (i->first == "health") {
351 h.SetHealth(GetNumber(*i->second));
352 } else if (i->first == "maxMana") {
353 h.SetMaxMana(GetNumber(*i->second));
354 } else if (i->first == "mana") {
355 h.SetMana(GetNumber(*i->second));
356 } else if (i->first == "ip") {
357 h.SetIP(GetNumber(*i->second));
358 } else if (i->first == "stats") {
360 ReadStats(stats, *GetPropertyList(*i->second));
362 } else if (i->first == "attackAnimation") {
363 h.SetAttackAnimation(GetAnimation(*i->second));
364 } else if (i->first == "spellAnimation") {
365 h.SetSpellAnimation(GetAnimation(*i->second));
366 } else if (i->first == "meleeAnimation") {
367 h.SetMeleeAnimation(GetAnimation(*i->second));
369 throw Error("unknown Hero property: " + i->first);
374 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
375 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
376 if (i->first == "name") {
377 m.SetName(GetString(*i->second));
378 } else if (i->first == "sprite") {
379 m.SetSprite(GetSprite(*i->second));
380 } else if (i->first == "level") {
381 m.SetLevel(GetNumber(*i->second));
382 } else if (i->first == "maxHealth") {
383 m.SetMaxHealth(GetNumber(*i->second));
384 } else if (i->first == "health") {
385 m.SetHealth(GetNumber(*i->second));
386 } else if (i->first == "maxMana") {
387 m.SetMaxMana(GetNumber(*i->second));
388 } else if (i->first == "mana") {
389 m.SetMana(GetNumber(*i->second));
390 } else if (i->first == "stats") {
392 ReadStats(stats, *GetPropertyList(*i->second));
394 } else if (i->first == "attackAnimation") {
395 m.SetAttackAnimation(GetAnimation(*i->second));
396 } else if (i->first == "meleeAnimation") {
397 m.SetMeleeAnimation(GetAnimation(*i->second));
399 throw Error("unknown Monster property: " + i->first);
404 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
405 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
406 if (i->first == "sprite") {
407 a.SetSprite(GetSprite(*i->second));
408 } else if (i->first == "frametime") {
409 a.SetFrameTime(GetNumber(*i->second));
410 } else if (i->first == "repeat") {
411 a.SetRepeat(GetBoolean(*i->second));
412 } else if (i->first == "framecount") {
413 a.SetNumFrames(GetNumber(*i->second));
414 } else if (i->first == "col") {
415 a.SetCol(GetNumber(*i->second));
416 } else if (i->first == "row") {
417 a.SetRow(GetNumber(*i->second));
419 throw Error("unknown SimpleAnimation property: " + i->first);
424 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
425 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
426 if (i->first == "image") {
427 s.SetSurface(GetImage(*i->second));
428 } else if (i->first == "size") {
429 s.SetSize(GetVector(*i->second));
430 } else if (i->first == "offset") {
431 s.SetOffset(GetVector(*i->second));
433 throw Error("unknown Sprite property: " + i->first);
438 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
439 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
440 if (i->first == "atp") {
441 s.SetAttack(GetNumber(*i->second));
442 } else if (i->first == "dfp") {
443 s.SetDefense(GetNumber(*i->second));
444 } else if (i->first == "str") {
445 s.SetStrength(GetNumber(*i->second));
446 } else if (i->first == "agl") {
447 s.SetAgility(GetNumber(*i->second));
448 } else if (i->first == "int") {
449 s.SetIntelligence(GetNumber(*i->second));
450 } else if (i->first == "gut") {
451 s.SetGut(GetNumber(*i->second));
452 } else if (i->first == "mgr") {
453 s.SetMagicResistance(GetNumber(*i->second));
455 throw Error("unknown Stats property: " + i->first);