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 using battle::Monster;
20 using graphics::Animation;
21 using graphics::ComplexAnimation;
22 using graphics::SimpleAnimation;
23 using graphics::Sprite;
24 using geometry::Vector;
32 void Interpreter::ReadSource() {
33 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
34 ReadDefinition(source.GetDefinition(*i));
38 void Interpreter::ReadDefinition(const Definition &dfn) {
39 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
42 if (dfn.HasLiteralValue()) {
49 void Interpreter::ReadLiteral(const Definition &dfn) {
50 switch (dfn.GetLiteral()->GetType()) {
51 case Literal::ARRAY_VALUES:
52 throw Error("unhandled literal: array of values");
54 case Literal::ARRAY_PROPS:
55 throw Error("unhandled literal: array of properties");
57 case Literal::BOOLEAN:
58 throw Error("unhandled literal: boolean");
61 throw Error("unhandled literal: color");
64 numbers[dfn.Identifier()] = dfn.GetLiteral()->GetNumber();
67 throw Error("unhandled literal: string");
70 throw Error("unhandled literal: vector");
73 throw Error("unhandled literal: object");
78 Animation *Interpreter::GetAnimation(const Value &v) {
80 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
81 ComplexAnimation *a(new ComplexAnimation);
82 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
85 SimpleAnimation *a(new SimpleAnimation);
86 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
89 } else if (animations.count(v.GetIdentifier())) {
90 return animations[v.GetIdentifier()];
91 } else if (source.IsDefined(v.GetIdentifier())) {
92 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
93 if (animations.count(v.GetIdentifier())) {
94 return animations[v.GetIdentifier()];
96 throw Error("cannot use " + source.GetDefinition(v.GetIdentifier()).Identifier() + " " + v.GetIdentifier() + " as animation");
99 throw Error("use of undefined Animation " + v.GetIdentifier());
103 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
105 return v.GetLiteral().GetValues();
107 throw Error("identifier resolution not implemented for arrays of values");
111 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
113 return v.GetLiteral().GetPropertyLists();
115 throw Error("identifier resolution not implemented for arrays of property lists");
119 bool Interpreter::GetBoolean(const Value &v) {
121 return v.GetLiteral().GetBoolean();
123 throw Error("identifier resolution not implemented for booleans");
127 SDL_Surface *Interpreter::GetImage(const Value &v) {
129 // TODO: image lookup
132 throw Error("identifier resolution not implemented for images");
136 int Interpreter::GetNumber(const Value &v) {
138 return v.GetLiteral().GetNumber();
139 } else if (numbers.count(v.GetIdentifier())) {
140 return numbers[v.GetIdentifier()];
142 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
143 if (numbers.count(v.GetIdentifier())) {
144 return numbers[v.GetIdentifier()];
146 throw Error("use of undefined Number " + v.GetIdentifier());
151 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
153 return v.GetLiteral().GetProperties();
155 throw Error("identifier resolution not implemented for property lists");
159 Sprite *Interpreter::GetSprite(const Value &v) {
161 Sprite *s(new Sprite);
162 ReadSprite(*s, *v.GetLiteral().GetProperties());
164 } else if (sprites.count(v.GetIdentifier())) {
165 return sprites[v.GetIdentifier()];
167 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
168 if (sprites.count(v.GetIdentifier())) {
169 return sprites[v.GetIdentifier()];
171 throw Error("use of undefined Sprite " + v.GetIdentifier());
176 const char *Interpreter::GetString(const Value &v) {
178 return v.GetLiteral().GetString().c_str();
180 throw Error("identifier resolution not implemented for strings");
184 Vector<int> Interpreter::GetVector(const Value &v) {
186 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
188 throw Error("identifier resolution not implemented for vectors");
193 void Interpreter::ReadObject(const Definition &dfn) {
194 if (dfn.TypeName() == "Hero") {
196 ReadHero(*h, *dfn.GetProperties());
197 heroes[dfn.Identifier()] = h;
198 } else if (dfn.TypeName() == "Monster") {
199 Monster *m(new Monster);
200 ReadMonster(*m, *dfn.GetProperties());
201 monsters[dfn.Identifier()] = m;
202 } else if (dfn.TypeName() == "Sprite") {
203 Sprite *s(new Sprite);
204 ReadSprite(*s, *dfn.GetProperties());
205 sprites[dfn.Identifier()] = s;
207 throw Error("unhandled object: " + dfn.TypeName());
212 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
213 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
214 if (i->first == "sprite") {
215 a.SetSprite(GetSprite(*i->second));
216 } else if (i->first == "frametime") {
217 a.SetFrameTime(GetNumber(*i->second));
218 } else if (i->first == "repeat") {
219 a.SetRepeat(GetBoolean(*i->second));
220 } else if (i->first == "frames") {
221 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
222 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
223 ComplexAnimation::FrameProp frame;
224 ReadComplexAnimationFrame(frame, **i);
228 throw Error("unknown ComplexAnimation property: " + i->first);
233 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
234 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
235 if (i->first == "column") {
236 f.col = GetNumber(*i->second);
237 } else if (i->first == "row") {
238 f.row = GetNumber(*i->second);
239 } else if (i->first == "disposition") {
240 f.disposition = GetVector(*i->second);
242 throw Error("unknown ComplexAnimationFrame property: " + i->first);
247 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
248 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
249 if (i->first == "name") {
250 h.SetName(GetString(*i->second));
251 } else if (i->first == "sprite") {
252 h.SetSprite(GetSprite(*i->second));
253 } else if (i->first == "level") {
254 h.SetLevel(GetNumber(*i->second));
255 } else if (i->first == "maxHealth") {
256 h.SetMaxHealth(GetNumber(*i->second));
257 } else if (i->first == "health") {
258 h.SetHealth(GetNumber(*i->second));
259 } else if (i->first == "maxMana") {
260 h.SetMaxMana(GetNumber(*i->second));
261 } else if (i->first == "mana") {
262 h.SetMana(GetNumber(*i->second));
263 } else if (i->first == "ip") {
264 h.SetIP(GetNumber(*i->second));
265 } else if (i->first == "stats") {
267 ReadStats(stats, *GetPropertyList(*i->second));
269 } else if (i->first == "attackAnimation") {
270 h.SetAttackAnimation(GetAnimation(*i->second));
271 } else if (i->first == "spellAnimation") {
272 h.SetSpellAnimation(GetAnimation(*i->second));
273 } else if (i->first == "meleeAnimation") {
274 h.SetMeleeAnimation(GetAnimation(*i->second));
276 throw Error("unknown Hero property: " + i->first);
281 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
282 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
283 if (i->first == "name") {
284 m.SetName(GetString(*i->second));
285 } else if (i->first == "sprite") {
286 m.SetSprite(GetSprite(*i->second));
287 } else if (i->first == "level") {
288 m.SetLevel(GetNumber(*i->second));
289 } else if (i->first == "maxHealth") {
290 m.SetMaxHealth(GetNumber(*i->second));
291 } else if (i->first == "health") {
292 m.SetHealth(GetNumber(*i->second));
293 } else if (i->first == "maxMana") {
294 m.SetMaxMana(GetNumber(*i->second));
295 } else if (i->first == "mana") {
296 m.SetMana(GetNumber(*i->second));
297 } else if (i->first == "stats") {
299 ReadStats(stats, *GetPropertyList(*i->second));
301 } else if (i->first == "attackAnimation") {
302 m.SetAttackAnimation(GetAnimation(*i->second));
304 throw Error("unknown Monster property: " + i->first);
309 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
310 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
311 if (i->first == "sprite") {
312 a.SetSprite(GetSprite(*i->second));
313 } else if (i->first == "frametime") {
314 a.SetFrameTime(GetNumber(*i->second));
315 } else if (i->first == "repeat") {
316 a.SetRepeat(GetBoolean(*i->second));
317 } else if (i->first == "framecount") {
318 a.SetNumFrames(GetNumber(*i->second));
319 } else if (i->first == "col") {
320 a.SetCol(GetNumber(*i->second));
321 } else if (i->first == "row") {
322 a.SetRow(GetNumber(*i->second));
324 throw Error("unknown SimpleAnimation property: " + i->first);
329 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
330 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
331 if (i->first == "image") {
332 s.SetSurface(GetImage(*i->second));
333 } else if (i->first == "size") {
334 s.SetSize(GetVector(*i->second));
335 } else if (i->first == "offset") {
336 s.SetOffset(GetVector(*i->second));
338 throw Error("unknown Sprite property: " + i->first);
343 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
344 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
345 if (i->first == "atp") {
346 s.SetAttack(GetNumber(*i->second));
347 } else if (i->first == "dfp") {
348 s.SetDefense(GetNumber(*i->second));
349 } else if (i->first == "str") {
350 s.SetStrength(GetNumber(*i->second));
351 } else if (i->first == "agl") {
352 s.SetAgility(GetNumber(*i->second));
353 } else if (i->first == "int") {
354 s.SetIntelligence(GetNumber(*i->second));
355 } else if (i->first == "gut") {
356 s.SetGut(GetNumber(*i->second));
357 } else if (i->first == "mgr") {
358 s.SetMagicResistance(GetNumber(*i->second));
360 throw Error("unknown Stats property: " + i->first);