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