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<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
46 bool Interpreter::ParsedDefinition::IsCompatible(DynamicType with) const {
49 && (type == COMPLEX_ANIMATION || type == SIMPLE_ANIMATION));
53 Animation *Interpreter::GetAnimation(const std::string &name) {
54 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
55 if (i != parsedDefinitions.end()) {
56 if (i->second.IsCompatible(ANIMATION)) {
57 return animations[i->second.index];
59 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
62 throw Error("access to undefined Animation " + name);
66 Hero *Interpreter::GetHero(const std::string &name) {
67 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
68 if (i != parsedDefinitions.end()) {
69 if (i->second.IsCompatible(HERO)) {
70 return &heroes[i->second.index];
72 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
75 throw Error("access to undefined Hero " + name);
79 Monster *Interpreter::GetMonster(const std::string &name) {
80 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
81 if (i != parsedDefinitions.end()) {
82 if (i->second.IsCompatible(MONSTER)) {
83 return &monsters[i->second.index];
85 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
88 throw Error("access to undefined Monster " + name);
92 int Interpreter::GetNumber(const std::string &name) const {
93 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
94 if (i != parsedDefinitions.end()) {
95 if (i->second.IsCompatible(NUMBER)) {
96 return numbers[i->second.index];
98 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
101 throw Error("access to undefined Number " + name);
105 Sprite *Interpreter::GetSprite(const std::string &name) {
106 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
107 if (i != parsedDefinitions.end()) {
108 if (i->second.IsCompatible(SPRITE)) {
109 return &sprites[i->second.index];
111 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
114 throw Error("access to undefined Sprite " + name);
119 void Interpreter::ReadSource() {
120 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
121 ReadDefinition(source.GetDefinition(*i));
125 void Interpreter::ReadDefinition(const Definition &dfn) {
126 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
129 if (dfn.HasLiteralValue()) {
136 void Interpreter::ReadLiteral(const Definition &dfn) {
137 switch (dfn.GetLiteral()->GetType()) {
138 case Literal::ARRAY_VALUES:
139 throw Error("unhandled literal: array of values");
141 case Literal::ARRAY_PROPS:
142 throw Error("unhandled literal: array of properties");
144 case Literal::BOOLEAN:
145 throw Error("unhandled literal: boolean");
148 throw Error("unhandled literal: color");
150 case Literal::NUMBER:
151 numbers.push_back(dfn.GetLiteral()->GetNumber());
152 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
154 case Literal::STRING:
155 throw Error("unhandled literal: string");
157 case Literal::VECTOR:
158 throw Error("unhandled literal: vector");
160 case Literal::OBJECT:
161 throw Error("unhandled literal: object");
166 Animation *Interpreter::GetAnimation(const Value &v) {
168 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
169 ComplexAnimation *a(new ComplexAnimation);
170 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
171 animations.push_back(a);
174 SimpleAnimation *a(new SimpleAnimation);
175 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
176 animations.push_back(a);
180 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
181 return GetAnimation(v.GetIdentifier());
185 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
187 return v.GetLiteral().GetValues();
189 throw Error("identifier resolution not implemented for arrays of values");
193 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
195 return v.GetLiteral().GetPropertyLists();
197 throw Error("identifier resolution not implemented for arrays of property lists");
201 bool Interpreter::GetBoolean(const Value &v) {
203 return v.GetLiteral().GetBoolean();
205 throw Error("identifier resolution not implemented for booleans");
209 SDL_Surface *Interpreter::GetImage(const Value &v) {
210 const char *file(GetString(v));
211 SDL_Surface *image(IMG_Load(file));
212 images.push_back(image);
216 int Interpreter::GetNumber(const Value &v) {
218 return v.GetLiteral().GetNumber();
220 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
221 return GetNumber(v.GetIdentifier());
225 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
227 return v.GetLiteral().GetProperties();
229 throw Error("identifier resolution not implemented for property lists");
233 Sprite *Interpreter::GetSprite(const Value &v) {
235 Sprite *s(new Sprite);
236 ReadSprite(*s, *v.GetLiteral().GetProperties());
239 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
240 return GetSprite(v.GetIdentifier());
244 const char *Interpreter::GetString(const Value &v) {
246 return v.GetLiteral().GetString().c_str();
248 throw Error("identifier resolution not implemented for strings");
252 Vector<int> Interpreter::GetVector(const Value &v) {
254 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
256 throw Error("identifier resolution not implemented for vectors");
261 void Interpreter::ReadObject(const Definition &dfn) {
262 if (dfn.TypeName() == "Hero") {
263 heroes.push_back(Hero());
264 ReadHero(heroes.back(), *dfn.GetProperties());
265 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, heroes.size() - 1)));
266 } else if (dfn.TypeName() == "Monster") {
267 monsters.push_back(Monster());
268 ReadMonster(monsters.back(), *dfn.GetProperties());
269 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, monsters.size() - 1)));
270 } else if (dfn.TypeName() == "Sprite") {
271 sprites.push_back(Sprite());
272 ReadSprite(sprites.back(), *dfn.GetProperties());
273 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, sprites.size() - 1)));
275 throw Error("unhandled object type: " + dfn.TypeName());
280 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
281 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
282 if (i->first == "sprite") {
283 a.SetSprite(GetSprite(*i->second));
284 } else if (i->first == "frametime") {
285 a.SetFrameTime(GetNumber(*i->second));
286 } else if (i->first == "repeat") {
287 a.SetRepeat(GetBoolean(*i->second));
288 } else if (i->first == "frames") {
289 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
290 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
291 ComplexAnimation::FrameProp frame;
292 ReadComplexAnimationFrame(frame, **i);
296 throw Error("unknown ComplexAnimation property: " + i->first);
301 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
302 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
303 if (i->first == "column") {
304 f.col = GetNumber(*i->second);
305 } else if (i->first == "row") {
306 f.row = GetNumber(*i->second);
307 } else if (i->first == "disposition") {
308 f.disposition = GetVector(*i->second);
310 throw Error("unknown ComplexAnimationFrame property: " + i->first);
315 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
316 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
317 if (i->first == "name") {
318 h.SetName(GetString(*i->second));
319 } else if (i->first == "sprite") {
320 h.SetSprite(GetSprite(*i->second));
321 } else if (i->first == "level") {
322 h.SetLevel(GetNumber(*i->second));
323 } else if (i->first == "maxHealth") {
324 h.SetMaxHealth(GetNumber(*i->second));
325 } else if (i->first == "health") {
326 h.SetHealth(GetNumber(*i->second));
327 } else if (i->first == "maxMana") {
328 h.SetMaxMana(GetNumber(*i->second));
329 } else if (i->first == "mana") {
330 h.SetMana(GetNumber(*i->second));
331 } else if (i->first == "ip") {
332 h.SetIP(GetNumber(*i->second));
333 } else if (i->first == "stats") {
335 ReadStats(stats, *GetPropertyList(*i->second));
337 } else if (i->first == "attackAnimation") {
338 h.SetAttackAnimation(GetAnimation(*i->second));
339 } else if (i->first == "spellAnimation") {
340 h.SetSpellAnimation(GetAnimation(*i->second));
341 } else if (i->first == "meleeAnimation") {
342 h.SetMeleeAnimation(GetAnimation(*i->second));
344 throw Error("unknown Hero property: " + i->first);
349 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
350 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
351 if (i->first == "name") {
352 m.SetName(GetString(*i->second));
353 } else if (i->first == "sprite") {
354 m.SetSprite(GetSprite(*i->second));
355 } else if (i->first == "level") {
356 m.SetLevel(GetNumber(*i->second));
357 } else if (i->first == "maxHealth") {
358 m.SetMaxHealth(GetNumber(*i->second));
359 } else if (i->first == "health") {
360 m.SetHealth(GetNumber(*i->second));
361 } else if (i->first == "maxMana") {
362 m.SetMaxMana(GetNumber(*i->second));
363 } else if (i->first == "mana") {
364 m.SetMana(GetNumber(*i->second));
365 } else if (i->first == "stats") {
367 ReadStats(stats, *GetPropertyList(*i->second));
369 } else if (i->first == "attackAnimation") {
370 m.SetAttackAnimation(GetAnimation(*i->second));
372 throw Error("unknown Monster property: " + i->first);
377 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
378 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
379 if (i->first == "sprite") {
380 a.SetSprite(GetSprite(*i->second));
381 } else if (i->first == "frametime") {
382 a.SetFrameTime(GetNumber(*i->second));
383 } else if (i->first == "repeat") {
384 a.SetRepeat(GetBoolean(*i->second));
385 } else if (i->first == "framecount") {
386 a.SetNumFrames(GetNumber(*i->second));
387 } else if (i->first == "col") {
388 a.SetCol(GetNumber(*i->second));
389 } else if (i->first == "row") {
390 a.SetRow(GetNumber(*i->second));
392 throw Error("unknown SimpleAnimation property: " + i->first);
397 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
398 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
399 if (i->first == "image") {
400 s.SetSurface(GetImage(*i->second));
401 } else if (i->first == "size") {
402 s.SetSize(GetVector(*i->second));
403 } else if (i->first == "offset") {
404 s.SetOffset(GetVector(*i->second));
406 throw Error("unknown Sprite property: " + i->first);
411 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
412 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
413 if (i->first == "atp") {
414 s.SetAttack(GetNumber(*i->second));
415 } else if (i->first == "dfp") {
416 s.SetDefense(GetNumber(*i->second));
417 } else if (i->first == "str") {
418 s.SetStrength(GetNumber(*i->second));
419 } else if (i->first == "agl") {
420 s.SetAgility(GetNumber(*i->second));
421 } else if (i->first == "int") {
422 s.SetIntelligence(GetNumber(*i->second));
423 } else if (i->first == "gut") {
424 s.SetGut(GetNumber(*i->second));
425 } else if (i->first == "mgr") {
426 s.SetMagicResistance(GetNumber(*i->second));
428 throw Error("unknown Stats property: " + i->first);