]> git.localhorst.tv Git - l2e.git/blob - src/loader/Interpreter.cpp
added interpretation of Ikari and Item
[l2e.git] / src / loader / Interpreter.cpp
1 /*
2  * Interpreter.cpp
3  *
4  *  Created on: Aug 26, 2012
5  *      Author: holy
6  */
7
8 #include "Interpreter.h"
9
10 #include "ParsedSource.h"
11 #include "../battle/Hero.h"
12 #include "../battle/Monster.h"
13 #include "../battle/PartyLayout.h"
14 #include "../common/Ikari.h"
15 #include "../common/Item.h"
16 #include "../common/Spell.h"
17 #include "../common/TargetingMode.h"
18 #include "../graphics/ComplexAnimation.h"
19 #include "../graphics/Font.h"
20 #include "../graphics/Frame.h"
21 #include "../graphics/Gauge.h"
22 #include "../graphics/SimpleAnimation.h"
23 #include "../graphics/Sprite.h"
24
25 #include <algorithm>
26 #include <cstring>
27 #include <SDL_image.h>
28
29 using battle::Hero;
30 using battle::Monster;
31 using battle::PartyLayout;
32 using battle::Stats;
33 using common::Ikari;
34 using common::Item;
35 using common::Spell;
36 using common::TargetingMode;
37 using graphics::Animation;
38 using graphics::Font;
39 using graphics::Frame;
40 using graphics::Gauge;
41 using graphics::ComplexAnimation;
42 using graphics::SimpleAnimation;
43 using graphics::Sprite;
44 using geometry::Vector;
45 using std::make_pair;
46 using std::map;
47 using std::set;
48 using std::string;
49 using std::vector;
50
51 namespace loader {
52
53 Interpreter::~Interpreter() {
54         for (vector<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.end()); i != end; ++i) {
55                 delete *i;
56         }
57         for (vector<Font *>::const_iterator i(fonts.begin()), end(fonts.end()); i != end; ++i) {
58                 delete *i;
59         }
60         for (vector<Frame *>::const_iterator i(frames.begin()), end(frames.end()); i != end; ++i) {
61                 delete *i;
62         }
63         for (vector<Gauge *>::const_iterator i(gauges.begin()), end(gauges.end()); i != end; ++i) {
64                 delete *i;
65         }
66         for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
67                 delete *i;
68         }
69         for (vector<Ikari *>::const_iterator i(ikaris.begin()), end(ikaris.end()); i != end; ++i) {
70                 delete *i;
71         }
72         for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
73                 SDL_FreeSurface(*i);
74         }
75         for (vector<Item *>::const_iterator i(items.begin()), end(items.end()); i != end; ++i) {
76                 delete *i;
77         }
78         for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
79                 delete *i;
80         }
81         for (vector<PartyLayout *>::const_iterator i(partyLayouts.begin()), end(partyLayouts.end()); i != end; ++i) {
82                 delete *i;
83         }
84         for (vector<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
85                 delete *i;
86         }
87         for (vector<Spell *>::const_iterator i(spells.begin()), end(spells.end()); i != end; ++i) {
88                 delete *i;
89         }
90         for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
91                 delete *i;
92         }
93         for (vector<const char *>::const_iterator i(strings.begin()), end(strings.end()); i != end; ++i) {
94                 delete *i;
95         }
96         for (vector<TargetingMode *>::const_iterator i(targetingModes.begin()), end(targetingModes.end()); i != end; ++i) {
97                 delete *i;
98         }
99 }
100
101
102 Animation *Interpreter::GetAnimation(const std::string &name) {
103         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
104         if (i != parsedDefinitions.end()) {
105                 if (i->second.type == COMPLEX_ANIMATION) {
106                         return complexAnimations[i->second.index];
107                 } else if (i->second.type == SIMPLE_ANIMATION) {
108                         return simpleAnimations[i->second.index];
109                 } else {
110                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
111                 }
112         } else {
113                 throw Error("access to undefined Animation " + name);
114         }
115 }
116
117 bool Interpreter::GetBoolean(const std::string &name) const {
118         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
119         if (i != parsedDefinitions.end()) {
120                 if (i->second.type == BOOLEAN) {
121                         return booleans[i->second.index];
122                 } else {
123                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Boolean");
124                 }
125         } else {
126                 throw Error("access to undefined Boolean " + name);
127         }
128 }
129
130 Font *Interpreter::GetFont(const std::string &name) {
131         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
132         if (i != parsedDefinitions.end()) {
133                 if (i->second.type == FONT) {
134                         return fonts[i->second.index];
135                 } else {
136                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Font");
137                 }
138         } else {
139                 throw Error("access to undefined Font " + name);
140         }
141 }
142
143 Frame *Interpreter::GetFrame(const std::string &name) {
144         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
145         if (i != parsedDefinitions.end()) {
146                 if (i->second.type == FRAME) {
147                         return frames[i->second.index];
148                 } else {
149                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Frame");
150                 }
151         } else {
152                 throw Error("access to undefined Frame " + name);
153         }
154 }
155
156 Gauge *Interpreter::GetGauge(const std::string &name) {
157         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
158         if (i != parsedDefinitions.end()) {
159                 if (i->second.type == GAUGE) {
160                         return gauges[i->second.index];
161                 } else {
162                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Gauge");
163                 }
164         } else {
165                 throw Error("access to undefined Gauge " + name);
166         }
167 }
168
169 Hero *Interpreter::GetHero(const std::string &name) {
170         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
171         if (i != parsedDefinitions.end()) {
172                 if (i->second.type == HERO) {
173                         return heroes[i->second.index];
174                 } else {
175                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
176                 }
177         } else {
178                 throw Error("access to undefined Hero " + name);
179         }
180 }
181
182 Ikari *Interpreter::GetIkari(const std::string &name) {
183         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
184         if (i != parsedDefinitions.end()) {
185                 if (i->second.type == IKARI) {
186                         return ikaris[i->second.index];
187                 } else {
188                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Ikari");
189                 }
190         } else {
191                 throw Error("access to undefined Ikari " + name);
192         }
193 }
194
195 Item *Interpreter::GetItem(const std::string &name) {
196         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
197         if (i != parsedDefinitions.end()) {
198                 if (i->second.type == ITEM) {
199                         return items[i->second.index];
200                 } else {
201                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Item");
202                 }
203         } else {
204                 throw Error("access to undefined Item " + name);
205         }
206 }
207
208 Monster *Interpreter::GetMonster(const std::string &name) {
209         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
210         if (i != parsedDefinitions.end()) {
211                 if (i->second.type == MONSTER) {
212                         return monsters[i->second.index];
213                 } else {
214                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
215                 }
216         } else {
217                 throw Error("access to undefined Monster " + name);
218         }
219 }
220
221 int Interpreter::GetNumber(const std::string &name) const {
222         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
223         if (i != parsedDefinitions.end()) {
224                 if (i->second.type == NUMBER) {
225                         return numbers[i->second.index];
226                 } else {
227                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
228                 }
229         } else {
230                 throw Error("access to undefined Number " + name);
231         }
232 }
233
234 PartyLayout *Interpreter::GetPartyLayout(const std::string &name) {
235         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
236         if (i != parsedDefinitions.end()) {
237                 if (i->second.type == PARTY_LAYOUT) {
238                         return partyLayouts[i->second.index];
239                 } else {
240                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to PartyLayout");
241                 }
242         } else {
243                 throw Error("access to undefined PartyLayout " + name);
244         }
245 }
246
247 Spell *Interpreter::GetSpell(const std::string &name) {
248         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
249         if (i != parsedDefinitions.end()) {
250                 if (i->second.type == SPELL) {
251                         return spells[i->second.index];
252                 } else {
253                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Spell");
254                 }
255         } else {
256                 throw Error("access to undefined Spell " + name);
257         }
258 }
259
260 Sprite *Interpreter::GetSprite(const std::string &name) {
261         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
262         if (i != parsedDefinitions.end()) {
263                 if (i->second.type == SPRITE) {
264                         return sprites[i->second.index];
265                 } else {
266                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
267                 }
268         } else {
269                 throw Error("access to undefined Sprite " + name);
270         }
271 }
272
273 const char *Interpreter::GetString(const std::string &name) const {
274         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
275         if (i != parsedDefinitions.end()) {
276                 if (i->second.type == STRING) {
277                         return strings[i->second.index];
278                 } else {
279                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to String");
280                 }
281         } else {
282                 throw Error("access to undefined String " + name);
283         }
284 }
285
286 TargetingMode *Interpreter::GetTargetingMode(const std::string &name) {
287         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
288         if (i != parsedDefinitions.end()) {
289                 if (i->second.type == TARGETING_MODE) {
290                         return targetingModes[i->second.index];
291                 } else {
292                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to TargetingMode");
293                 }
294         } else {
295                 throw Error("access to undefined TargetingMode " + name);
296         }
297 }
298
299 Vector<int> Interpreter::GetVector(const std::string &name) const {
300         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
301         if (i != parsedDefinitions.end()) {
302                 if (i->second.type == VECTOR) {
303                         return vectors[i->second.index];
304                 } else {
305                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Vector");
306                 }
307         } else {
308                 throw Error("access to undefined Vector " + name);
309         }
310 }
311
312
313 void Interpreter::ReadSource() {
314         for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
315                 ReadDefinition(source.GetDefinition(*i));
316         }
317 }
318
319 void Interpreter::ReadDefinition(const Definition &dfn) {
320         if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
321                 return;
322         }
323         if (dfn.HasLiteralValue()) {
324                 ReadLiteral(dfn);
325         } else {
326                 ReadObject(dfn);
327         }
328 }
329
330 void Interpreter::ReadLiteral(const Definition &dfn) {
331         switch (dfn.GetLiteral()->GetType()) {
332                 case Literal::ARRAY_VALUES:
333                         valueArrays.push_back(dfn.GetLiteral()->GetValues());
334                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VALUE_ARRAY, valueArrays.size() - 1)));
335                         break;
336                 case Literal::ARRAY_PROPS:
337                         propertyListArrays.push_back(dfn.GetLiteral()->GetPropertyLists());
338                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PROPERTY_LIST_ARRAY, propertyListArrays.size() - 1)));
339                         break;
340                 case Literal::BOOLEAN:
341                         booleans.push_back(dfn.GetLiteral()->GetBoolean());
342                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BOOLEAN, booleans.size() - 1)));
343                         break;
344                 case Literal::COLOR:
345                         throw Error("unhandled literal: color");
346                         break;
347                 case Literal::NUMBER:
348                         numbers.push_back(dfn.GetLiteral()->GetNumber());
349                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
350                         break;
351                 case Literal::STRING:
352                         {
353                                 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
354                                 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
355                                 str[dfn.GetLiteral()->GetString().size()] = '\0';
356                                 strings.push_back(str);
357                         }
358                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, STRING, strings.size() - 1)));
359                         break;
360                 case Literal::VECTOR:
361                         vectors.push_back(Vector<int>(dfn.GetLiteral()->GetX(), dfn.GetLiteral()->GetY()));
362                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VECTOR, vectors.size() - 1)));
363                         break;
364                 case Literal::OBJECT:
365                         ReadObject(dfn);
366                         break;
367         }
368 }
369
370 Animation *Interpreter::GetAnimation(const Value &v) {
371         if (v.IsLiteral()) {
372                 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
373                         ComplexAnimation *a(new ComplexAnimation);
374                         ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
375                         complexAnimations.push_back(a);
376                         return a;
377                 } else {
378                         SimpleAnimation *a(new SimpleAnimation);
379                         ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
380                         simpleAnimations.push_back(a);
381                         return a;
382                 }
383         } else {
384                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
385                 return GetAnimation(v.GetIdentifier());
386         }
387 }
388
389 bool Interpreter::GetBoolean(const Value &v) {
390         if (v.IsLiteral()) {
391                 return v.GetLiteral().GetBoolean();
392         } else {
393                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
394                 return GetBoolean(v.GetIdentifier());
395         }
396 }
397
398 Font *Interpreter::GetFont(const Value &v) {
399         if (v.IsLiteral()) {
400                 Font *f(new Font);
401                 ReadFont(*f, *v.GetLiteral().GetProperties());
402                 return f;
403         } else {
404                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
405                 return GetFont(v.GetIdentifier());
406         }
407 }
408
409 Frame *Interpreter::GetFrame(const Value &v) {
410         if (v.IsLiteral()) {
411                 Frame *f(new Frame);
412                 ReadFrame(*f, *v.GetLiteral().GetProperties());
413                 return f;
414         } else {
415                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
416                 return GetFrame(v.GetIdentifier());
417         }
418 }
419
420 Gauge *Interpreter::GetGauge(const Value &v) {
421         if (v.IsLiteral()) {
422                 Gauge *g(new Gauge);
423                 ReadGauge(*g, *v.GetLiteral().GetProperties());
424                 return g;
425         } else {
426                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
427                 return GetGauge(v.GetIdentifier());
428         }
429 }
430
431 Hero *Interpreter::GetHero(const Value &v) {
432         if (v.IsLiteral()) {
433                 Hero *h(new Hero);
434                 ReadHero(*h, *v.GetLiteral().GetProperties());
435                 return h;
436         } else {
437                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
438                 return GetHero(v.GetIdentifier());
439         }
440 }
441
442 Ikari *Interpreter::GetIkari(const Value &v) {
443         if (v.IsLiteral()) {
444                 Ikari *i(new Ikari);
445                 ReadIkari(*i, *v.GetLiteral().GetProperties());
446                 return i;
447         } else {
448                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
449                 return GetIkari(v.GetIdentifier());
450         }
451 }
452
453 SDL_Surface *Interpreter::GetImage(const Value &v) {
454         const char *file(GetString(v));
455         SDL_Surface *image(IMG_Load(file));
456         images.push_back(image);
457         return image;
458 }
459
460 Item *Interpreter::GetItem(const Value &v) {
461         if (v.IsLiteral()) {
462                 Item *i(new Item);
463                 ReadItem(*i, *v.GetLiteral().GetProperties());
464                 return i;
465         } else {
466                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
467                 return GetItem(v.GetIdentifier());
468         }
469 }
470
471 int Interpreter::GetNumber(const Value &v) {
472         if (v.IsLiteral()) {
473                 return v.GetLiteral().GetNumber();
474         } else {
475                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
476                 return GetNumber(v.GetIdentifier());
477         }
478 }
479
480 PartyLayout *Interpreter::GetPartyLayout(const Value &v) {
481         if (v.IsLiteral()) {
482                 PartyLayout *l(new PartyLayout);
483                 ReadPartyLayout(*l, *v.GetLiteral().GetProperties());
484                 return l;
485         } else {
486                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
487                 return GetPartyLayout(v.GetIdentifier());
488         }
489 }
490
491 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
492         if (v.IsLiteral()) {
493                 return v.GetLiteral().GetProperties();
494         } else {
495                 throw Error("cannot reference property lists");
496         }
497 }
498
499 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
500         if (v.IsLiteral()) {
501                 return v.GetLiteral().GetPropertyLists();
502         } else {
503                 throw Error("cannot reference property list arrays");
504         }
505 }
506
507 Spell *Interpreter::GetSpell(const Value &v) {
508         if (v.IsLiteral()) {
509                 Spell *s(new Spell);
510                 ReadSpell(*s, *v.GetLiteral().GetProperties());
511                 return s;
512         } else {
513                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
514                 return GetSpell(v.GetIdentifier());
515         }
516 }
517
518 Sprite *Interpreter::GetSprite(const Value &v) {
519         if (v.IsLiteral()) {
520                 Sprite *s(new Sprite);
521                 ReadSprite(*s, *v.GetLiteral().GetProperties());
522                 return s;
523         } else {
524                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
525                 return GetSprite(v.GetIdentifier());
526         }
527 }
528
529 const char *Interpreter::GetString(const Value &v) {
530         if (v.IsLiteral()) {
531                 return v.GetLiteral().GetString().c_str();
532         } else {
533                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
534                 return GetString(v.GetIdentifier());
535         }
536 }
537
538 TargetingMode *Interpreter::GetTargetingMode(const Value &v) {
539         if (v.IsLiteral()) {
540                 TargetingMode *t(new TargetingMode);
541                 ReadTargetingMode(*t, *v.GetLiteral().GetProperties());
542                 return t;
543         } else {
544                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
545                 return GetTargetingMode(v.GetIdentifier());
546         }
547 }
548
549 Vector<int> Interpreter::GetVector(const Value &v) {
550         if (v.IsLiteral()) {
551                 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
552         } else {
553                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
554                 return GetVector(v.GetIdentifier());
555         }
556 }
557
558 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
559         if (v.IsLiteral()) {
560                 return v.GetLiteral().GetValues();
561         } else {
562                 throw Error("cannot reference value arrays");
563         }
564 }
565
566
567 void Interpreter::ReadObject(const Definition &dfn) {
568         if (dfn.TypeName() == "ComplexAnimation") {
569                 ComplexAnimation *animation(new ComplexAnimation);
570                 int index(complexAnimations.size());
571                 complexAnimations.push_back(animation);
572                 ReadComplexAnimation(*animation, *dfn.GetProperties());
573                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
574         } else if (dfn.TypeName() == "Font") {
575                 Font *font(new Font);
576                 int index(fonts.size());
577                 fonts.push_back(font);
578                 ReadFont(*font, *dfn.GetProperties());
579                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FONT, index)));
580         } else if (dfn.TypeName() == "Frame") {
581                 Frame *frame(new Frame);
582                 int index(frames.size());
583                 frames.push_back(frame);
584                 ReadFrame(*frame, *dfn.GetProperties());
585                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FRAME, index)));
586         } else if (dfn.TypeName() == "Gauge") {
587                 Gauge *gauge(new Gauge);
588                 int index(gauges.size());
589                 gauges.push_back(gauge);
590                 ReadGauge(*gauge, *dfn.GetProperties());
591                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, GAUGE, index)));
592         } else if (dfn.TypeName() == "Hero") {
593                 Hero *hero(new Hero);
594                 int index(heroes.size());
595                 heroes.push_back(hero);
596                 ReadHero(*hero, *dfn.GetProperties());
597                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
598         } else if (dfn.TypeName() == "Ikari") {
599                 Ikari *ikari(new Ikari);
600                 int index(ikaris.size());
601                 ikaris.push_back(ikari);
602                 ReadIkari(*ikari, *dfn.GetProperties());
603                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, IKARI, index)));
604         } else if (dfn.TypeName() == "Item") {
605                 Item *item(new Item);
606                 int index(items.size());
607                 items.push_back(item);
608                 ReadItem(*item, *dfn.GetProperties());
609                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, ITEM, index)));
610         } else if (dfn.TypeName() == "Monster") {
611                 Monster *monster(new Monster);
612                 int index(monsters.size());
613                 monsters.push_back(monster);
614                 ReadMonster(*monster, *dfn.GetProperties());
615                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
616         } else if (dfn.TypeName() == "PartyLayout") {
617                 PartyLayout *layout(new PartyLayout);
618                 int index(partyLayouts.size());
619                 partyLayouts.push_back(layout);
620                 ReadPartyLayout(*layout, *dfn.GetProperties());
621                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PARTY_LAYOUT, index)));
622         } else if (dfn.TypeName() == "SimpleAnimation") {
623                 SimpleAnimation *animation(new SimpleAnimation);
624                 int index(simpleAnimations.size());
625                 simpleAnimations.push_back(animation);
626                 ReadSimpleAnimation(*animation, *dfn.GetProperties());
627                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
628         } else if (dfn.TypeName() == "Spell") {
629                 Spell *spell(new Spell);
630                 int index(spells.size());
631                 spells.push_back(spell);
632                 ReadSpell(*spell, *dfn.GetProperties());
633                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPELL, index)));
634         } else if (dfn.TypeName() == "Sprite") {
635                 Sprite *sprite(new Sprite);
636                 int index(sprites.size());
637                 sprites.push_back(sprite);
638                 ReadSprite(*sprite, *dfn.GetProperties());
639                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
640         } else if (dfn.TypeName() == "TargetingMode") {
641                 TargetingMode *mode(new TargetingMode);
642                 int index(targetingModes.size());
643                 targetingModes.push_back(mode);
644                 ReadTargetingMode(*mode, *dfn.GetProperties());
645                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, TARGETING_MODE, index)));
646         } else {
647                 throw Error("unhandled object type: " + dfn.TypeName());
648         }
649 }
650
651
652 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
653         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
654                 if (i->first == "sprite") {
655                         a.SetSprite(GetSprite(*i->second));
656                 } else if (i->first == "frametime") {
657                         a.SetFrameTime(GetNumber(*i->second));
658                 } else if (i->first == "repeat") {
659                         a.SetRepeat(GetBoolean(*i->second));
660                 } else if (i->first == "frames") {
661                         const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
662                         for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
663                                 ComplexAnimation::FrameProp frame;
664                                 ReadComplexAnimationFrame(frame, **i);
665                                 a.AddFrame(frame);
666                         }
667                 } else {
668                         throw Error("unknown ComplexAnimation property: " + i->first);
669                 }
670         }
671 }
672
673 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
674         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
675                 if (i->first == "column") {
676                         f.col = GetNumber(*i->second);
677                 } else if (i->first == "row") {
678                         f.row = GetNumber(*i->second);
679                 } else if (i->first == "disposition") {
680                         f.disposition = GetVector(*i->second);
681                 } else {
682                         throw Error("unknown ComplexAnimationFrame property: " + i->first);
683                 }
684         }
685 }
686
687 void Interpreter::ReadFont(Font &f, const PropertyList &props) {
688         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
689                 if (i->first == "sprite") {
690                         f.SetSprite(GetSprite(*i->second));
691                 } else if (i->first == "columnoffset") {
692                         f.SetColOffset(GetNumber(*i->second));
693                 } else if (i->first == "rowoffset") {
694                         f.SetRowOffset(GetNumber(*i->second));
695                 } else {
696                         throw Error("unknown Font property: " + i->first);
697                 }
698         }
699 }
700
701 void Interpreter::ReadFrame(Frame &f, const PropertyList &props) {
702         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
703                 if (i->first == "image") {
704                         f.SetSurface(GetImage(*i->second));
705                 } else if (i->first == "border") {
706                         f.SetBorderSize(GetVector(*i->second));
707                 } else if (i->first == "repeat") {
708                         f.SetRepeatSize(GetVector(*i->second));
709                 } else if (i->first == "offset") {
710                         f.SetOffset(GetVector(*i->second));
711                 } else {
712                         throw Error("unknown Frame property: " + i->first);
713                 }
714         }
715 }
716
717 void Interpreter::ReadGauge(Gauge &g, const PropertyList &props) {
718         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
719                 if (i->first == "image") {
720                         g.SetSurface(GetImage(*i->second));
721                 } else if (i->first == "full") {
722                         g.SetFullOffset(GetVector(*i->second));
723                 } else if (i->first == "empty") {
724                         g.SetEmptyOffset(GetVector(*i->second));
725                 } else if (i->first == "height") {
726                         g.SetHeight(GetNumber(*i->second));
727                 } else if (i->first == "start") {
728                         g.SetStartWidth(GetNumber(*i->second));
729                 } else if (i->first == "repeat") {
730                         g.SetRepeatWidth(GetNumber(*i->second));
731                 } else if (i->first == "end") {
732                         g.SetEndWidth(GetNumber(*i->second));
733                 } else {
734                         throw Error("unknown Gauge property: " + i->first);
735                 }
736         }
737 }
738
739 void Interpreter::ReadIkari(Ikari &ikari, const PropertyList &props) {
740         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
741                 if (i->first == "name") {
742                         ikari.SetName(GetString(*i->second));
743                 } else if (i->first == "cost") {
744                         ikari.SetCost(GetNumber(*i->second));
745                 } else if (i->first == "targets") {
746                         ikari.GetTargetingMode() = *GetTargetingMode(*i->second);
747                 } else if (i->first == "magical") {
748                         if (GetBoolean(*i->second)) {
749                                 ikari.SetMagical();
750                         }
751                 } else if (i->first == "physical") {
752                         if (GetBoolean(*i->second)) {
753                                 ikari.SetPhysical();
754                         }
755                 } else {
756                         throw Error("unknown Ikari property: " + i->first);
757                 }
758         }
759 }
760
761 void Interpreter::ReadItem(Item &item, const PropertyList &props) {
762         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
763                 if (i->first == "name") {
764                         item.SetName(GetString(*i->second));
765                 } else if (i->first == "menuicon") {
766                         item.SetMenuIcon(GetSprite(*i->second));
767                 } else if (i->first == "battle") {
768                         if (GetBoolean(*i->second)) {
769                                 item.SetUsableInBattle();
770                         }
771                 } else if (i->first == "targets") {
772                         item.GetTargetingMode() = *GetTargetingMode(*i->second);
773                 } else if (i->first == "ikari") {
774                         item.SetIkari(GetIkari(*i->second));
775                 } else if (i->first == "attackanimation") {
776                         item.SetAttackAnimation(GetAnimation(*i->second));
777                 } else {
778                         throw Error("unknown Item property: " + i->first);
779                 }
780         }
781 }
782
783 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
784         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
785                 if (i->first == "name") {
786                         h.SetName(GetString(*i->second));
787                 } else if (i->first == "sprite") {
788                         h.SetSprite(GetSprite(*i->second));
789                 } else if (i->first == "level") {
790                         h.SetLevel(GetNumber(*i->second));
791                 } else if (i->first == "maxHealth") {
792                         h.SetMaxHealth(GetNumber(*i->second));
793                 } else if (i->first == "health") {
794                         h.SetHealth(GetNumber(*i->second));
795                 } else if (i->first == "maxMana") {
796                         h.SetMaxMana(GetNumber(*i->second));
797                 } else if (i->first == "mana") {
798                         h.SetMana(GetNumber(*i->second));
799                 } else if (i->first == "ip") {
800                         h.SetIP(GetNumber(*i->second));
801                 } else if (i->first == "stats") {
802                         battle::Stats stats;
803                         ReadStats(stats, *GetPropertyList(*i->second));
804                         h.SetStats(stats);
805                 } else if (i->first == "attackAnimation") {
806                         h.SetAttackAnimation(GetAnimation(*i->second));
807                 } else if (i->first == "spellAnimation") {
808                         h.SetSpellAnimation(GetAnimation(*i->second));
809                 } else if (i->first == "meleeAnimation") {
810                         h.SetMeleeAnimation(GetAnimation(*i->second));
811                 } else {
812                         throw Error("unknown Hero property: " + i->first);
813                 }
814         }
815 }
816
817 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
818         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
819                 if (i->first == "name") {
820                         m.SetName(GetString(*i->second));
821                 } else if (i->first == "sprite") {
822                         m.SetSprite(GetSprite(*i->second));
823                 } else if (i->first == "level") {
824                         m.SetLevel(GetNumber(*i->second));
825                 } else if (i->first == "maxHealth") {
826                         m.SetMaxHealth(GetNumber(*i->second));
827                 } else if (i->first == "health") {
828                         m.SetHealth(GetNumber(*i->second));
829                 } else if (i->first == "maxMana") {
830                         m.SetMaxMana(GetNumber(*i->second));
831                 } else if (i->first == "mana") {
832                         m.SetMana(GetNumber(*i->second));
833                 } else if (i->first == "stats") {
834                         battle::Stats stats;
835                         ReadStats(stats, *GetPropertyList(*i->second));
836                         m.SetStats(stats);
837                 } else if (i->first == "attackAnimation") {
838                         m.SetAttackAnimation(GetAnimation(*i->second));
839                 } else if (i->first == "meleeAnimation") {
840                         m.SetMeleeAnimation(GetAnimation(*i->second));
841                 } else {
842                         throw Error("unknown Monster property: " + i->first);
843                 }
844         }
845 }
846
847 void Interpreter::ReadPartyLayout(PartyLayout &p, const PropertyList &props) {
848         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
849                 if (i->first == "positions") {
850                         const vector<Value *> &positions(GetValueArray(*i->second));
851                         for (vector<Value *>::const_iterator j(positions.begin()), end(positions.end()); j != end; ++j) {
852                                 p.AddPosition(GetVector(**j));
853                         }
854                 } else {
855                         throw Error("unknown PartyLayout property: " + i->first);
856                 }
857         }
858 }
859
860 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
861         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
862                 if (i->first == "sprite") {
863                         a.SetSprite(GetSprite(*i->second));
864                 } else if (i->first == "frametime") {
865                         a.SetFrameTime(GetNumber(*i->second));
866                 } else if (i->first == "repeat") {
867                         a.SetRepeat(GetBoolean(*i->second));
868                 } else if (i->first == "framecount") {
869                         a.SetNumFrames(GetNumber(*i->second));
870                 } else if (i->first == "col") {
871                         a.SetCol(GetNumber(*i->second));
872                 } else if (i->first == "row") {
873                         a.SetRow(GetNumber(*i->second));
874                 } else {
875                         throw Error("unknown SimpleAnimation property: " + i->first);
876                 }
877         }
878 }
879
880 void Interpreter::ReadSpell(Spell &s, const PropertyList &props) {
881         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
882                 if (i->first == "name") {
883                         s.SetName(GetString(*i->second));
884                 } else if (i->first == "cost") {
885                         s.SetCost(GetNumber(*i->second));
886                 } else if (i->first == "battle") {
887                         if (GetBoolean(*i->second)) {
888                                 s.SetUsableInBattle();
889                         }
890                 } else if (i->first == "targets") {
891                         s.GetTargetingMode() = *GetTargetingMode(*i->second);
892                 } else {
893                         throw Error("unknown Spell property: " + i->first);
894                 }
895         }
896 }
897
898 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
899         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
900                 if (i->first == "image") {
901                         s.SetSurface(GetImage(*i->second));
902                 } else if (i->first == "size") {
903                         s.SetSize(GetVector(*i->second));
904                 } else if (i->first == "offset") {
905                         s.SetOffset(GetVector(*i->second));
906                 } else {
907                         throw Error("unknown Sprite property: " + i->first);
908                 }
909         }
910 }
911
912 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
913         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
914                 if (i->first == "atp") {
915                         s.SetAttack(GetNumber(*i->second));
916                 } else if (i->first == "dfp") {
917                         s.SetDefense(GetNumber(*i->second));
918                 } else if (i->first == "str") {
919                         s.SetStrength(GetNumber(*i->second));
920                 } else if (i->first == "agl") {
921                         s.SetAgility(GetNumber(*i->second));
922                 } else if (i->first == "int") {
923                         s.SetIntelligence(GetNumber(*i->second));
924                 } else if (i->first == "gut") {
925                         s.SetGut(GetNumber(*i->second));
926                 } else if (i->first == "mgr") {
927                         s.SetMagicResistance(GetNumber(*i->second));
928                 } else {
929                         throw Error("unknown Stats property: " + i->first);
930                 }
931         }
932 }
933
934 void Interpreter::ReadTargetingMode(TargetingMode &t, const PropertyList &props) {
935         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
936                 if (i->first == "ally") {
937                         if (GetBoolean(*i->second)) {
938                                 t.TargetAlly();
939                         } else {
940                                 t.TargetEnemy();
941                         }
942                 } else if (i->first == "enemy") {
943                         if (GetBoolean(*i->second)) {
944                                 t.TargetEnemy();
945                         } else {
946                                 t.TargetAlly();
947                         }
948                 } else if (i->first == "all") {
949                         if (GetBoolean(*i->second)) {
950                                 t.TargetAll();
951                         }
952                 } else if (i->first == "multiple") {
953                         if (GetBoolean(*i->second)) {
954                                 t.TargetMultiple();
955                         }
956                 } else if (i->first == "single") {
957                         if (GetBoolean(*i->second)) {
958                                 t.TargetSingle();
959                         }
960                 } else {
961                         throw Error("unknown TargetingMode property: " + i->first);
962                 }
963         }
964 }
965
966 }