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"
17 #include <SDL_image.h>
20 using battle::Monster;
22 using graphics::Animation;
23 using graphics::ComplexAnimation;
24 using graphics::SimpleAnimation;
25 using graphics::Sprite;
26 using geometry::Vector;
34 Animation *Interpreter::GetAnimation(const std::string &name) {
35 map<string, Animation *>::const_iterator i(animations.find(name));
36 if (i != animations.end()) {
39 throw Error("access to undefined Animation " + name);
43 Hero *Interpreter::GetHero(const std::string &name) {
44 map<string, Hero *>::const_iterator i(heroes.find(name));
45 if (i != heroes.end()) {
48 throw Error("access to undefined Hero " + name);
52 Monster *Interpreter::GetMonster(const std::string &name) {
53 map<string, Monster *>::const_iterator i(monsters.find(name));
54 if (i != monsters.end()) {
57 throw Error("access to undefined Monster " + name);
61 int Interpreter::GetNumber(const std::string &name) const {
62 map<string, int>::const_iterator i(numbers.find(name));
63 if (i != numbers.end()) {
66 throw Error("access to undefined Number " + name);
70 Sprite *Interpreter::GetSprite(const std::string &name) {
71 map<string, Sprite *>::const_iterator i(sprites.find(name));
72 if (i != sprites.end()) {
75 throw Error("access to undefined Sprite " + name);
80 void Interpreter::ReadSource() {
81 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
82 ReadDefinition(source.GetDefinition(*i));
86 void Interpreter::ReadDefinition(const Definition &dfn) {
87 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
90 if (dfn.HasLiteralValue()) {
97 void Interpreter::ReadLiteral(const Definition &dfn) {
98 switch (dfn.GetLiteral()->GetType()) {
99 case Literal::ARRAY_VALUES:
100 throw Error("unhandled literal: array of values");
102 case Literal::ARRAY_PROPS:
103 throw Error("unhandled literal: array of properties");
105 case Literal::BOOLEAN:
106 throw Error("unhandled literal: boolean");
109 throw Error("unhandled literal: color");
111 case Literal::NUMBER:
112 numbers[dfn.Identifier()] = dfn.GetLiteral()->GetNumber();
114 case Literal::STRING:
115 throw Error("unhandled literal: string");
117 case Literal::VECTOR:
118 throw Error("unhandled literal: vector");
120 case Literal::OBJECT:
121 throw Error("unhandled literal: object");
126 Animation *Interpreter::GetAnimation(const Value &v) {
128 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
129 ComplexAnimation *a(new ComplexAnimation);
130 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
133 SimpleAnimation *a(new SimpleAnimation);
134 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
137 } else if (animations.count(v.GetIdentifier())) {
138 return animations[v.GetIdentifier()];
139 } else if (source.IsDefined(v.GetIdentifier())) {
140 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
141 if (animations.count(v.GetIdentifier())) {
142 return animations[v.GetIdentifier()];
144 throw Error("cannot use " + source.GetDefinition(v.GetIdentifier()).Identifier() + " " + v.GetIdentifier() + " as animation");
147 throw Error("use of undefined Animation " + v.GetIdentifier());
151 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
153 return v.GetLiteral().GetValues();
155 throw Error("identifier resolution not implemented for arrays of values");
159 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
161 return v.GetLiteral().GetPropertyLists();
163 throw Error("identifier resolution not implemented for arrays of property lists");
167 bool Interpreter::GetBoolean(const Value &v) {
169 return v.GetLiteral().GetBoolean();
171 throw Error("identifier resolution not implemented for booleans");
175 SDL_Surface *Interpreter::GetImage(const Value &v) {
176 const char *file(GetString(v));
177 return IMG_Load(file);
180 int Interpreter::GetNumber(const Value &v) {
182 return v.GetLiteral().GetNumber();
183 } else if (numbers.count(v.GetIdentifier())) {
184 return numbers[v.GetIdentifier()];
186 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
187 if (numbers.count(v.GetIdentifier())) {
188 return numbers[v.GetIdentifier()];
190 throw Error("use of undefined Number " + v.GetIdentifier());
195 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
197 return v.GetLiteral().GetProperties();
199 throw Error("identifier resolution not implemented for property lists");
203 Sprite *Interpreter::GetSprite(const Value &v) {
205 Sprite *s(new Sprite);
206 ReadSprite(*s, *v.GetLiteral().GetProperties());
208 } else if (sprites.count(v.GetIdentifier())) {
209 return sprites[v.GetIdentifier()];
211 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
212 if (sprites.count(v.GetIdentifier())) {
213 return sprites[v.GetIdentifier()];
215 throw Error("use of undefined Sprite " + v.GetIdentifier());
220 const char *Interpreter::GetString(const Value &v) {
222 return v.GetLiteral().GetString().c_str();
224 throw Error("identifier resolution not implemented for strings");
228 Vector<int> Interpreter::GetVector(const Value &v) {
230 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
232 throw Error("identifier resolution not implemented for vectors");
237 void Interpreter::ReadObject(const Definition &dfn) {
238 if (dfn.TypeName() == "Hero") {
240 ReadHero(*h, *dfn.GetProperties());
241 heroes[dfn.Identifier()] = h;
242 } else if (dfn.TypeName() == "Monster") {
243 Monster *m(new Monster);
244 ReadMonster(*m, *dfn.GetProperties());
245 monsters[dfn.Identifier()] = m;
246 } else if (dfn.TypeName() == "Sprite") {
247 Sprite *s(new Sprite);
248 ReadSprite(*s, *dfn.GetProperties());
249 sprites[dfn.Identifier()] = s;
251 throw Error("unhandled object: " + dfn.TypeName());
256 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
257 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
258 if (i->first == "sprite") {
259 a.SetSprite(GetSprite(*i->second));
260 } else if (i->first == "frametime") {
261 a.SetFrameTime(GetNumber(*i->second));
262 } else if (i->first == "repeat") {
263 a.SetRepeat(GetBoolean(*i->second));
264 } else if (i->first == "frames") {
265 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
266 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
267 ComplexAnimation::FrameProp frame;
268 ReadComplexAnimationFrame(frame, **i);
272 throw Error("unknown ComplexAnimation property: " + i->first);
277 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
278 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
279 if (i->first == "column") {
280 f.col = GetNumber(*i->second);
281 } else if (i->first == "row") {
282 f.row = GetNumber(*i->second);
283 } else if (i->first == "disposition") {
284 f.disposition = GetVector(*i->second);
286 throw Error("unknown ComplexAnimationFrame property: " + i->first);
291 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
292 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
293 if (i->first == "name") {
294 h.SetName(GetString(*i->second));
295 } else if (i->first == "sprite") {
296 h.SetSprite(GetSprite(*i->second));
297 } else if (i->first == "level") {
298 h.SetLevel(GetNumber(*i->second));
299 } else if (i->first == "maxHealth") {
300 h.SetMaxHealth(GetNumber(*i->second));
301 } else if (i->first == "health") {
302 h.SetHealth(GetNumber(*i->second));
303 } else if (i->first == "maxMana") {
304 h.SetMaxMana(GetNumber(*i->second));
305 } else if (i->first == "mana") {
306 h.SetMana(GetNumber(*i->second));
307 } else if (i->first == "ip") {
308 h.SetIP(GetNumber(*i->second));
309 } else if (i->first == "stats") {
311 ReadStats(stats, *GetPropertyList(*i->second));
313 } else if (i->first == "attackAnimation") {
314 h.SetAttackAnimation(GetAnimation(*i->second));
315 } else if (i->first == "spellAnimation") {
316 h.SetSpellAnimation(GetAnimation(*i->second));
317 } else if (i->first == "meleeAnimation") {
318 h.SetMeleeAnimation(GetAnimation(*i->second));
320 throw Error("unknown Hero property: " + i->first);
325 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
326 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
327 if (i->first == "name") {
328 m.SetName(GetString(*i->second));
329 } else if (i->first == "sprite") {
330 m.SetSprite(GetSprite(*i->second));
331 } else if (i->first == "level") {
332 m.SetLevel(GetNumber(*i->second));
333 } else if (i->first == "maxHealth") {
334 m.SetMaxHealth(GetNumber(*i->second));
335 } else if (i->first == "health") {
336 m.SetHealth(GetNumber(*i->second));
337 } else if (i->first == "maxMana") {
338 m.SetMaxMana(GetNumber(*i->second));
339 } else if (i->first == "mana") {
340 m.SetMana(GetNumber(*i->second));
341 } else if (i->first == "stats") {
343 ReadStats(stats, *GetPropertyList(*i->second));
345 } else if (i->first == "attackAnimation") {
346 m.SetAttackAnimation(GetAnimation(*i->second));
348 throw Error("unknown Monster property: " + i->first);
353 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
354 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
355 if (i->first == "sprite") {
356 a.SetSprite(GetSprite(*i->second));
357 } else if (i->first == "frametime") {
358 a.SetFrameTime(GetNumber(*i->second));
359 } else if (i->first == "repeat") {
360 a.SetRepeat(GetBoolean(*i->second));
361 } else if (i->first == "framecount") {
362 a.SetNumFrames(GetNumber(*i->second));
363 } else if (i->first == "col") {
364 a.SetCol(GetNumber(*i->second));
365 } else if (i->first == "row") {
366 a.SetRow(GetNumber(*i->second));
368 throw Error("unknown SimpleAnimation property: " + i->first);
373 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
374 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
375 if (i->first == "image") {
376 s.SetSurface(GetImage(*i->second));
377 } else if (i->first == "size") {
378 s.SetSize(GetVector(*i->second));
379 } else if (i->first == "offset") {
380 s.SetOffset(GetVector(*i->second));
382 throw Error("unknown Sprite property: " + i->first);
387 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
388 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
389 if (i->first == "atp") {
390 s.SetAttack(GetNumber(*i->second));
391 } else if (i->first == "dfp") {
392 s.SetDefense(GetNumber(*i->second));
393 } else if (i->first == "str") {
394 s.SetStrength(GetNumber(*i->second));
395 } else if (i->first == "agl") {
396 s.SetAgility(GetNumber(*i->second));
397 } else if (i->first == "int") {
398 s.SetIntelligence(GetNumber(*i->second));
399 } else if (i->first == "gut") {
400 s.SetGut(GetNumber(*i->second));
401 } else if (i->first == "mgr") {
402 s.SetMagicResistance(GetNumber(*i->second));
404 throw Error("unknown Stats property: " + i->first);