]> git.localhorst.tv Git - l2e.git/blob - src/loader/Interpreter.cpp
f616c1a394a0f803d0fee0a828b5f53abf3c32b0
[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 "../graphics/ComplexAnimation.h"
15 #include "../graphics/Font.h"
16 #include "../graphics/Frame.h"
17 #include "../graphics/Gauge.h"
18 #include "../graphics/SimpleAnimation.h"
19 #include "../graphics/Sprite.h"
20
21 #include <algorithm>
22 #include <cstring>
23 #include <SDL_image.h>
24
25 using battle::Hero;
26 using battle::Monster;
27 using battle::PartyLayout;
28 using battle::Stats;
29 using graphics::Animation;
30 using graphics::Font;
31 using graphics::Frame;
32 using graphics::Gauge;
33 using graphics::ComplexAnimation;
34 using graphics::SimpleAnimation;
35 using graphics::Sprite;
36 using geometry::Vector;
37 using std::make_pair;
38 using std::map;
39 using std::set;
40 using std::string;
41 using std::vector;
42
43 namespace loader {
44
45 Interpreter::~Interpreter() {
46         for (vector<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.end()); i != end; ++i) {
47                 delete *i;
48         }
49         for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
50                 delete *i;
51         }
52         for (vector<Font *>::const_iterator i(fonts.begin()), end(fonts.end()); i != end; ++i) {
53                 delete *i;
54         }
55         for (vector<Frame *>::const_iterator i(frames.begin()), end(frames.end()); i != end; ++i) {
56                 delete *i;
57         }
58         for (vector<Gauge *>::const_iterator i(gauges.begin()), end(gauges.end()); i != end; ++i) {
59                 delete *i;
60         }
61         for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
62                 SDL_FreeSurface(*i);
63         }
64         for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
65                 delete *i;
66         }
67         for (vector<PartyLayout *>::const_iterator i(partyLayouts.begin()), end(partyLayouts.end()); i != end; ++i) {
68                 delete *i;
69         }
70         for (vector<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
71                 delete *i;
72         }
73         for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
74                 delete *i;
75         }
76         for (vector<const char *>::const_iterator i(strings.begin()), end(strings.end()); i != end; ++i) {
77                 delete *i;
78         }
79 }
80
81
82 Animation *Interpreter::GetAnimation(const std::string &name) {
83         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
84         if (i != parsedDefinitions.end()) {
85                 if (i->second.type == COMPLEX_ANIMATION) {
86                         return complexAnimations[i->second.index];
87                 } else if (i->second.type == SIMPLE_ANIMATION) {
88                         return simpleAnimations[i->second.index];
89                 } else {
90                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
91                 }
92         } else {
93                 throw Error("access to undefined Animation " + name);
94         }
95 }
96
97 bool Interpreter::GetBoolean(const std::string &name) const {
98         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
99         if (i != parsedDefinitions.end()) {
100                 if (i->second.type == BOOLEAN) {
101                         return booleans[i->second.index];
102                 } else {
103                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Boolean");
104                 }
105         } else {
106                 throw Error("access to undefined Boolean " + name);
107         }
108 }
109
110 Font *Interpreter::GetFont(const std::string &name) {
111         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
112         if (i != parsedDefinitions.end()) {
113                 if (i->second.type == FONT) {
114                         return fonts[i->second.index];
115                 } else {
116                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Font");
117                 }
118         } else {
119                 throw Error("access to undefined Font " + name);
120         }
121 }
122
123 Frame *Interpreter::GetFrame(const std::string &name) {
124         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
125         if (i != parsedDefinitions.end()) {
126                 if (i->second.type == FRAME) {
127                         return frames[i->second.index];
128                 } else {
129                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Frame");
130                 }
131         } else {
132                 throw Error("access to undefined Frame " + name);
133         }
134 }
135
136 Gauge *Interpreter::GetGauge(const std::string &name) {
137         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
138         if (i != parsedDefinitions.end()) {
139                 if (i->second.type == GAUGE) {
140                         return gauges[i->second.index];
141                 } else {
142                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Gauge");
143                 }
144         } else {
145                 throw Error("access to undefined Gauge " + name);
146         }
147 }
148
149 Hero *Interpreter::GetHero(const std::string &name) {
150         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
151         if (i != parsedDefinitions.end()) {
152                 if (i->second.type == HERO) {
153                         return heroes[i->second.index];
154                 } else {
155                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
156                 }
157         } else {
158                 throw Error("access to undefined Hero " + name);
159         }
160 }
161
162 Monster *Interpreter::GetMonster(const std::string &name) {
163         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
164         if (i != parsedDefinitions.end()) {
165                 if (i->second.type == MONSTER) {
166                         return monsters[i->second.index];
167                 } else {
168                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
169                 }
170         } else {
171                 throw Error("access to undefined Monster " + name);
172         }
173 }
174
175 int Interpreter::GetNumber(const std::string &name) const {
176         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
177         if (i != parsedDefinitions.end()) {
178                 if (i->second.type == NUMBER) {
179                         return numbers[i->second.index];
180                 } else {
181                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
182                 }
183         } else {
184                 throw Error("access to undefined Number " + name);
185         }
186 }
187
188 PartyLayout *Interpreter::GetPartyLayout(const std::string &name) {
189         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
190         if (i != parsedDefinitions.end()) {
191                 if (i->second.type == PARTY_LAYOUT) {
192                         return partyLayouts[i->second.index];
193                 } else {
194                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to PartyLayout");
195                 }
196         } else {
197                 throw Error("access to undefined PartyLayout " + name);
198         }
199 }
200
201 Sprite *Interpreter::GetSprite(const std::string &name) {
202         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
203         if (i != parsedDefinitions.end()) {
204                 if (i->second.type == SPRITE) {
205                         return sprites[i->second.index];
206                 } else {
207                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
208                 }
209         } else {
210                 throw Error("access to undefined Sprite " + name);
211         }
212 }
213
214 const char *Interpreter::GetString(const std::string &name) const {
215         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
216         if (i != parsedDefinitions.end()) {
217                 if (i->second.type == STRING) {
218                         return strings[i->second.index];
219                 } else {
220                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to String");
221                 }
222         } else {
223                 throw Error("access to undefined String " + name);
224         }
225 }
226
227 Vector<int> Interpreter::GetVector(const std::string &name) const {
228         map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
229         if (i != parsedDefinitions.end()) {
230                 if (i->second.type == VECTOR) {
231                         return vectors[i->second.index];
232                 } else {
233                         throw Error("cannot cast " + i->second.dfn->TypeName() + " to Vector");
234                 }
235         } else {
236                 throw Error("access to undefined Vector " + name);
237         }
238 }
239
240
241 void Interpreter::ReadSource() {
242         for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
243                 ReadDefinition(source.GetDefinition(*i));
244         }
245 }
246
247 void Interpreter::ReadDefinition(const Definition &dfn) {
248         if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
249                 return;
250         }
251         if (dfn.HasLiteralValue()) {
252                 ReadLiteral(dfn);
253         } else {
254                 ReadObject(dfn);
255         }
256 }
257
258 void Interpreter::ReadLiteral(const Definition &dfn) {
259         switch (dfn.GetLiteral()->GetType()) {
260                 case Literal::ARRAY_VALUES:
261                         valueArrays.push_back(dfn.GetLiteral()->GetValues());
262                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VALUE_ARRAY, valueArrays.size() - 1)));
263                         break;
264                 case Literal::ARRAY_PROPS:
265                         propertyListArrays.push_back(dfn.GetLiteral()->GetPropertyLists());
266                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PROPERTY_LIST_ARRAY, propertyListArrays.size() - 1)));
267                         break;
268                 case Literal::BOOLEAN:
269                         booleans.push_back(dfn.GetLiteral()->GetBoolean());
270                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BOOLEAN, booleans.size() - 1)));
271                         break;
272                 case Literal::COLOR:
273                         throw Error("unhandled literal: color");
274                         break;
275                 case Literal::NUMBER:
276                         numbers.push_back(dfn.GetLiteral()->GetNumber());
277                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
278                         break;
279                 case Literal::STRING:
280                         {
281                                 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
282                                 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
283                                 str[dfn.GetLiteral()->GetString().size()] = '\0';
284                                 strings.push_back(str);
285                         }
286                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, STRING, strings.size() - 1)));
287                         break;
288                 case Literal::VECTOR:
289                         vectors.push_back(Vector<int>(dfn.GetLiteral()->GetX(), dfn.GetLiteral()->GetY()));
290                         parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VECTOR, vectors.size() - 1)));
291                         break;
292                 case Literal::OBJECT:
293                         ReadObject(dfn);
294                         break;
295         }
296 }
297
298 Animation *Interpreter::GetAnimation(const Value &v) {
299         if (v.IsLiteral()) {
300                 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
301                         ComplexAnimation *a(new ComplexAnimation);
302                         ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
303                         complexAnimations.push_back(a);
304                         return a;
305                 } else {
306                         SimpleAnimation *a(new SimpleAnimation);
307                         ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
308                         simpleAnimations.push_back(a);
309                         return a;
310                 }
311         } else {
312                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
313                 return GetAnimation(v.GetIdentifier());
314         }
315 }
316
317 bool Interpreter::GetBoolean(const Value &v) {
318         if (v.IsLiteral()) {
319                 return v.GetLiteral().GetBoolean();
320         } else {
321                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
322                 return GetBoolean(v.GetIdentifier());
323         }
324 }
325
326 Font *Interpreter::GetFont(const Value &v) {
327         if (v.IsLiteral()) {
328                 Font *f(new Font);
329                 ReadFont(*f, *v.GetLiteral().GetProperties());
330                 return f;
331         } else {
332                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
333                 return GetFont(v.GetIdentifier());
334         }
335 }
336
337 Frame *Interpreter::GetFrame(const Value &v) {
338         if (v.IsLiteral()) {
339                 Frame *f(new Frame);
340                 ReadFrame(*f, *v.GetLiteral().GetProperties());
341                 return f;
342         } else {
343                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
344                 return GetFrame(v.GetIdentifier());
345         }
346 }
347
348 Gauge *Interpreter::GetGauge(const Value &v) {
349         if (v.IsLiteral()) {
350                 Gauge *g(new Gauge);
351                 ReadGauge(*g, *v.GetLiteral().GetProperties());
352                 return g;
353         } else {
354                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
355                 return GetGauge(v.GetIdentifier());
356         }
357 }
358
359 SDL_Surface *Interpreter::GetImage(const Value &v) {
360         const char *file(GetString(v));
361         SDL_Surface *image(IMG_Load(file));
362         images.push_back(image);
363         return image;
364 }
365
366 int Interpreter::GetNumber(const Value &v) {
367         if (v.IsLiteral()) {
368                 return v.GetLiteral().GetNumber();
369         } else {
370                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
371                 return GetNumber(v.GetIdentifier());
372         }
373 }
374
375 PartyLayout *Interpreter::GetPartyLayout(const Value &v) {
376         if (v.IsLiteral()) {
377                 PartyLayout *l(new PartyLayout);
378                 ReadPartyLayout(*l, *v.GetLiteral().GetProperties());
379                 return l;
380         } else {
381                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
382                 return GetPartyLayout(v.GetIdentifier());
383         }
384 }
385
386 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
387         if (v.IsLiteral()) {
388                 return v.GetLiteral().GetProperties();
389         } else {
390                 throw Error("cannot reference property lists");
391         }
392 }
393
394 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
395         if (v.IsLiteral()) {
396                 return v.GetLiteral().GetPropertyLists();
397         } else {
398                 throw Error("cannot reference property list arrays");
399         }
400 }
401
402 Sprite *Interpreter::GetSprite(const Value &v) {
403         if (v.IsLiteral()) {
404                 Sprite *s(new Sprite);
405                 ReadSprite(*s, *v.GetLiteral().GetProperties());
406                 return s;
407         } else {
408                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
409                 return GetSprite(v.GetIdentifier());
410         }
411 }
412
413 const char *Interpreter::GetString(const Value &v) {
414         if (v.IsLiteral()) {
415                 return v.GetLiteral().GetString().c_str();
416         } else {
417                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
418                 return GetString(v.GetIdentifier());
419         }
420 }
421
422 Vector<int> Interpreter::GetVector(const Value &v) {
423         if (v.IsLiteral()) {
424                 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
425         } else {
426                 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
427                 return GetVector(v.GetIdentifier());
428         }
429 }
430
431 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
432         if (v.IsLiteral()) {
433                 return v.GetLiteral().GetValues();
434         } else {
435                 throw Error("cannot reference value arrays");
436         }
437 }
438
439
440 void Interpreter::ReadObject(const Definition &dfn) {
441         if (dfn.TypeName() == "ComplexAnimation") {
442                 ComplexAnimation *animation(new ComplexAnimation);
443                 int index(complexAnimations.size());
444                 complexAnimations.push_back(animation);
445                 ReadComplexAnimation(*animation, *dfn.GetProperties());
446                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
447         } else if (dfn.TypeName() == "Font") {
448                 Font *font(new Font);
449                 int index(fonts.size());
450                 fonts.push_back(font);
451                 ReadFont(*font, *dfn.GetProperties());
452                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FONT, index)));
453         } else if (dfn.TypeName() == "Frame") {
454                 Frame *frame(new Frame);
455                 int index(frames.size());
456                 frames.push_back(frame);
457                 ReadFrame(*frame, *dfn.GetProperties());
458                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FRAME, index)));
459         } else if (dfn.TypeName() == "Gauge") {
460                 Gauge *gauge(new Gauge);
461                 int index(gauges.size());
462                 gauges.push_back(gauge);
463                 ReadGauge(*gauge, *dfn.GetProperties());
464                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, GAUGE, index)));
465         } else if (dfn.TypeName() == "Hero") {
466                 Hero *hero(new Hero);
467                 int index(heroes.size());
468                 heroes.push_back(hero);
469                 ReadHero(*hero, *dfn.GetProperties());
470                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
471         } else if (dfn.TypeName() == "Monster") {
472                 Monster *monster(new Monster);
473                 int index(monsters.size());
474                 monsters.push_back(monster);
475                 ReadMonster(*monster, *dfn.GetProperties());
476                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
477         } else if (dfn.TypeName() == "PartyLayout") {
478                 PartyLayout *layout(new PartyLayout);
479                 int index(partyLayouts.size());
480                 partyLayouts.push_back(layout);
481                 ReadPartyLayout(*layout, *dfn.GetProperties());
482                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PARTY_LAYOUT, index)));
483         } else if (dfn.TypeName() == "SimpleAnimation") {
484                 SimpleAnimation *animation(new SimpleAnimation);
485                 int index(simpleAnimations.size());
486                 simpleAnimations.push_back(animation);
487                 ReadSimpleAnimation(*animation, *dfn.GetProperties());
488                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
489         } else if (dfn.TypeName() == "Sprite") {
490                 Sprite *sprite(new Sprite);
491                 int index(sprites.size());
492                 sprites.push_back(sprite);
493                 ReadSprite(*sprite, *dfn.GetProperties());
494                 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
495         } else {
496                 throw Error("unhandled object type: " + dfn.TypeName());
497         }
498 }
499
500
501 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
502         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
503                 if (i->first == "sprite") {
504                         a.SetSprite(GetSprite(*i->second));
505                 } else if (i->first == "frametime") {
506                         a.SetFrameTime(GetNumber(*i->second));
507                 } else if (i->first == "repeat") {
508                         a.SetRepeat(GetBoolean(*i->second));
509                 } else if (i->first == "frames") {
510                         const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
511                         for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
512                                 ComplexAnimation::FrameProp frame;
513                                 ReadComplexAnimationFrame(frame, **i);
514                                 a.AddFrame(frame);
515                         }
516                 } else {
517                         throw Error("unknown ComplexAnimation property: " + i->first);
518                 }
519         }
520 }
521
522 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
523         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
524                 if (i->first == "column") {
525                         f.col = GetNumber(*i->second);
526                 } else if (i->first == "row") {
527                         f.row = GetNumber(*i->second);
528                 } else if (i->first == "disposition") {
529                         f.disposition = GetVector(*i->second);
530                 } else {
531                         throw Error("unknown ComplexAnimationFrame property: " + i->first);
532                 }
533         }
534 }
535
536 void Interpreter::ReadFont(Font &f, const PropertyList &props) {
537         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
538                 if (i->first == "sprite") {
539                         f.SetSprite(GetSprite(*i->second));
540                 } else if (i->first == "columnoffset") {
541                         f.SetColOffset(GetNumber(*i->second));
542                 } else if (i->first == "rowoffset") {
543                         f.SetRowOffset(GetNumber(*i->second));
544                 } else {
545                         throw Error("unknown Font property: " + i->first);
546                 }
547         }
548 }
549
550 void Interpreter::ReadFrame(Frame &f, const PropertyList &props) {
551         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
552                 if (i->first == "image") {
553                         f.SetSurface(GetImage(*i->second));
554                 } else if (i->first == "border") {
555                         f.SetBorderSize(GetVector(*i->second));
556                 } else if (i->first == "repeat") {
557                         f.SetRepeatSize(GetVector(*i->second));
558                 } else if (i->first == "offset") {
559                         f.SetOffset(GetVector(*i->second));
560                 } else {
561                         throw Error("unknown Frame property: " + i->first);
562                 }
563         }
564 }
565
566 void Interpreter::ReadGauge(Gauge &g, const PropertyList &props) {
567         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
568                 if (i->first == "image") {
569                         g.SetSurface(GetImage(*i->second));
570                 } else if (i->first == "full") {
571                         g.SetFullOffset(GetVector(*i->second));
572                 } else if (i->first == "empty") {
573                         g.SetEmptyOffset(GetVector(*i->second));
574                 } else if (i->first == "height") {
575                         g.SetHeight(GetNumber(*i->second));
576                 } else if (i->first == "start") {
577                         g.SetStartWidth(GetNumber(*i->second));
578                 } else if (i->first == "repeat") {
579                         g.SetRepeatWidth(GetNumber(*i->second));
580                 } else if (i->first == "end") {
581                         g.SetEndWidth(GetNumber(*i->second));
582                 } else {
583                         throw Error("unknown Gauge property: " + i->first);
584                 }
585         }
586 }
587
588 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
589         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
590                 if (i->first == "name") {
591                         h.SetName(GetString(*i->second));
592                 } else if (i->first == "sprite") {
593                         h.SetSprite(GetSprite(*i->second));
594                 } else if (i->first == "level") {
595                         h.SetLevel(GetNumber(*i->second));
596                 } else if (i->first == "maxHealth") {
597                         h.SetMaxHealth(GetNumber(*i->second));
598                 } else if (i->first == "health") {
599                         h.SetHealth(GetNumber(*i->second));
600                 } else if (i->first == "maxMana") {
601                         h.SetMaxMana(GetNumber(*i->second));
602                 } else if (i->first == "mana") {
603                         h.SetMana(GetNumber(*i->second));
604                 } else if (i->first == "ip") {
605                         h.SetIP(GetNumber(*i->second));
606                 } else if (i->first == "stats") {
607                         battle::Stats stats;
608                         ReadStats(stats, *GetPropertyList(*i->second));
609                         h.SetStats(stats);
610                 } else if (i->first == "attackAnimation") {
611                         h.SetAttackAnimation(GetAnimation(*i->second));
612                 } else if (i->first == "spellAnimation") {
613                         h.SetSpellAnimation(GetAnimation(*i->second));
614                 } else if (i->first == "meleeAnimation") {
615                         h.SetMeleeAnimation(GetAnimation(*i->second));
616                 } else {
617                         throw Error("unknown Hero property: " + i->first);
618                 }
619         }
620 }
621
622 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
623         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
624                 if (i->first == "name") {
625                         m.SetName(GetString(*i->second));
626                 } else if (i->first == "sprite") {
627                         m.SetSprite(GetSprite(*i->second));
628                 } else if (i->first == "level") {
629                         m.SetLevel(GetNumber(*i->second));
630                 } else if (i->first == "maxHealth") {
631                         m.SetMaxHealth(GetNumber(*i->second));
632                 } else if (i->first == "health") {
633                         m.SetHealth(GetNumber(*i->second));
634                 } else if (i->first == "maxMana") {
635                         m.SetMaxMana(GetNumber(*i->second));
636                 } else if (i->first == "mana") {
637                         m.SetMana(GetNumber(*i->second));
638                 } else if (i->first == "stats") {
639                         battle::Stats stats;
640                         ReadStats(stats, *GetPropertyList(*i->second));
641                         m.SetStats(stats);
642                 } else if (i->first == "attackAnimation") {
643                         m.SetAttackAnimation(GetAnimation(*i->second));
644                 } else if (i->first == "meleeAnimation") {
645                         m.SetMeleeAnimation(GetAnimation(*i->second));
646                 } else {
647                         throw Error("unknown Monster property: " + i->first);
648                 }
649         }
650 }
651
652 void Interpreter::ReadPartyLayout(PartyLayout &p, const PropertyList &props) {
653         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
654                 if (i->first == "positions") {
655                         const vector<Value *> &positions(GetValueArray(*i->second));
656                         for (vector<Value *>::const_iterator j(positions.begin()), end(positions.end()); j != end; ++j) {
657                                 p.AddPosition(GetVector(**j));
658                         }
659                 } else {
660                         throw Error("unknown PartyLayout property: " + i->first);
661                 }
662         }
663 }
664
665 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
666         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
667                 if (i->first == "sprite") {
668                         a.SetSprite(GetSprite(*i->second));
669                 } else if (i->first == "frametime") {
670                         a.SetFrameTime(GetNumber(*i->second));
671                 } else if (i->first == "repeat") {
672                         a.SetRepeat(GetBoolean(*i->second));
673                 } else if (i->first == "framecount") {
674                         a.SetNumFrames(GetNumber(*i->second));
675                 } else if (i->first == "col") {
676                         a.SetCol(GetNumber(*i->second));
677                 } else if (i->first == "row") {
678                         a.SetRow(GetNumber(*i->second));
679                 } else {
680                         throw Error("unknown SimpleAnimation property: " + i->first);
681                 }
682         }
683 }
684
685 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
686         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
687                 if (i->first == "image") {
688                         s.SetSurface(GetImage(*i->second));
689                 } else if (i->first == "size") {
690                         s.SetSize(GetVector(*i->second));
691                 } else if (i->first == "offset") {
692                         s.SetOffset(GetVector(*i->second));
693                 } else {
694                         throw Error("unknown Sprite property: " + i->first);
695                 }
696         }
697 }
698
699 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
700         for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
701                 if (i->first == "atp") {
702                         s.SetAttack(GetNumber(*i->second));
703                 } else if (i->first == "dfp") {
704                         s.SetDefense(GetNumber(*i->second));
705                 } else if (i->first == "str") {
706                         s.SetStrength(GetNumber(*i->second));
707                 } else if (i->first == "agl") {
708                         s.SetAgility(GetNumber(*i->second));
709                 } else if (i->first == "int") {
710                         s.SetIntelligence(GetNumber(*i->second));
711                 } else if (i->first == "gut") {
712                         s.SetGut(GetNumber(*i->second));
713                 } else if (i->first == "mgr") {
714                         s.SetMagicResistance(GetNumber(*i->second));
715                 } else {
716                         throw Error("unknown Stats property: " + i->first);
717                 }
718         }
719 }
720
721 }