4 * Created on: Aug 26, 2012
8 #include "Interpreter.h"
10 #include "ParsedSource.h"
11 #include "../battle/Hero.h"
12 #include "../battle/Monster.h"
13 #include "../battle/PartyLayout.h"
14 #include "../battle/Resources.h"
15 #include "../common/Ikari.h"
16 #include "../common/Item.h"
17 #include "../common/Spell.h"
18 #include "../common/TargetingMode.h"
19 #include "../graphics/ComplexAnimation.h"
20 #include "../graphics/Font.h"
21 #include "../graphics/Frame.h"
22 #include "../graphics/Gauge.h"
23 #include "../graphics/Menu.h"
24 #include "../graphics/SimpleAnimation.h"
25 #include "../graphics/Sprite.h"
29 #include <SDL_image.h>
32 using battle::Monster;
33 using battle::PartyLayout;
38 using common::TargetingMode;
39 using graphics::Animation;
40 using graphics::Color;
42 using graphics::Frame;
43 using graphics::Gauge;
44 using graphics::ComplexAnimation;
45 using graphics::SimpleAnimation;
46 using graphics::Sprite;
47 using geometry::Vector;
56 Interpreter::~Interpreter() {
57 for (vector<battle::Resources *>::const_iterator i(battleResources.begin()), end(battleResources.end()); i != end; ++i) {
60 for (vector<ComplexAnimation *>::const_iterator i(complexAnimations.begin()), end(complexAnimations.end()); i != end; ++i) {
63 for (vector<Font *>::const_iterator i(fonts.begin()), end(fonts.end()); i != end; ++i) {
66 for (vector<Frame *>::const_iterator i(frames.begin()), end(frames.end()); i != end; ++i) {
69 for (vector<Gauge *>::const_iterator i(gauges.begin()), end(gauges.end()); i != end; ++i) {
72 for (vector<Hero *>::const_iterator i(heroes.begin()), end(heroes.end()); i != end; ++i) {
75 for (vector<Ikari *>::const_iterator i(ikaris.begin()), end(ikaris.end()); i != end; ++i) {
78 for (vector<SDL_Surface *>::const_iterator i(images.begin()), end(images.end()); i != end; ++i) {
81 for (vector<Item *>::const_iterator i(items.begin()), end(items.end()); i != end; ++i) {
84 for (vector<graphics::MenuProperties *>::const_iterator i(menuProperties.begin()), end(menuProperties.end()); i != end; ++i) {
87 for (vector<Monster *>::const_iterator i(monsters.begin()), end(monsters.end()); i != end; ++i) {
90 for (vector<PartyLayout *>::const_iterator i(partyLayouts.begin()), end(partyLayouts.end()); i != end; ++i) {
93 for (vector<SimpleAnimation *>::const_iterator i(simpleAnimations.begin()), end(simpleAnimations.end()); i != end; ++i) {
96 for (vector<Spell *>::const_iterator i(spells.begin()), end(spells.end()); i != end; ++i) {
99 for (vector<Sprite *>::const_iterator i(sprites.begin()), end(sprites.end()); i != end; ++i) {
102 for (vector<const char *>::const_iterator i(strings.begin()), end(strings.end()); i != end; ++i) {
105 for (vector<TargetingMode *>::const_iterator i(targetingModes.begin()), end(targetingModes.end()); i != end; ++i) {
111 Animation *Interpreter::GetAnimation(const std::string &name) {
112 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
113 if (i != parsedDefinitions.end()) {
114 if (i->second.type == COMPLEX_ANIMATION) {
115 return complexAnimations[i->second.index];
116 } else if (i->second.type == SIMPLE_ANIMATION) {
117 return simpleAnimations[i->second.index];
119 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Animation");
122 throw Error("access to undefined Animation " + name);
126 battle::Resources *Interpreter::GetBattleResources(const std::string &name) {
127 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
128 if (i != parsedDefinitions.end()) {
129 if (i->second.type == BATTLE_RESOURCES) {
130 return battleResources[i->second.index];
132 throw Error("cannot cast " + i->second.dfn->TypeName() + " to BattleResources");
135 throw Error("access to undefined BattleResources " + name);
139 bool Interpreter::GetBoolean(const std::string &name) const {
140 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
141 if (i != parsedDefinitions.end()) {
142 if (i->second.type == BOOLEAN) {
143 return booleans[i->second.index];
145 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Boolean");
148 throw Error("access to undefined Boolean " + name);
152 const Color &Interpreter::GetColor(const std::string &name) const {
153 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
154 if (i != parsedDefinitions.end()) {
155 if (i->second.type == COLOR) {
156 return colors[i->second.index];
158 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Color");
161 throw Error("access to undefined Color " + name);
165 Font *Interpreter::GetFont(const std::string &name) {
166 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
167 if (i != parsedDefinitions.end()) {
168 if (i->second.type == FONT) {
169 return fonts[i->second.index];
171 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Font");
174 throw Error("access to undefined Font " + name);
178 Frame *Interpreter::GetFrame(const std::string &name) {
179 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
180 if (i != parsedDefinitions.end()) {
181 if (i->second.type == FRAME) {
182 return frames[i->second.index];
184 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Frame");
187 throw Error("access to undefined Frame " + name);
191 Gauge *Interpreter::GetGauge(const std::string &name) {
192 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
193 if (i != parsedDefinitions.end()) {
194 if (i->second.type == GAUGE) {
195 return gauges[i->second.index];
197 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Gauge");
200 throw Error("access to undefined Gauge " + name);
204 Hero *Interpreter::GetHero(const std::string &name) {
205 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
206 if (i != parsedDefinitions.end()) {
207 if (i->second.type == HERO) {
208 return heroes[i->second.index];
210 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Hero");
213 throw Error("access to undefined Hero " + name);
217 Ikari *Interpreter::GetIkari(const std::string &name) {
218 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
219 if (i != parsedDefinitions.end()) {
220 if (i->second.type == IKARI) {
221 return ikaris[i->second.index];
223 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Ikari");
226 throw Error("access to undefined Ikari " + name);
230 Item *Interpreter::GetItem(const std::string &name) {
231 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
232 if (i != parsedDefinitions.end()) {
233 if (i->second.type == ITEM) {
234 return items[i->second.index];
236 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Item");
239 throw Error("access to undefined Item " + name);
243 graphics::MenuProperties *Interpreter::GetMenuProperties(const std::string &name) {
244 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
245 if (i != parsedDefinitions.end()) {
246 if (i->second.type == MENU_PROPERTIES) {
247 return menuProperties[i->second.index];
249 throw Error("cannot cast " + i->second.dfn->TypeName() + " to MenuProperties");
252 throw Error("access to undefined MenuProperties " + name);
256 Monster *Interpreter::GetMonster(const std::string &name) {
257 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
258 if (i != parsedDefinitions.end()) {
259 if (i->second.type == MONSTER) {
260 return monsters[i->second.index];
262 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Monster");
265 throw Error("access to undefined Monster " + name);
269 int Interpreter::GetNumber(const std::string &name) const {
270 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
271 if (i != parsedDefinitions.end()) {
272 if (i->second.type == NUMBER) {
273 return numbers[i->second.index];
275 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Number");
278 throw Error("access to undefined Number " + name);
282 PartyLayout *Interpreter::GetPartyLayout(const std::string &name) {
283 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
284 if (i != parsedDefinitions.end()) {
285 if (i->second.type == PARTY_LAYOUT) {
286 return partyLayouts[i->second.index];
288 throw Error("cannot cast " + i->second.dfn->TypeName() + " to PartyLayout");
291 throw Error("access to undefined PartyLayout " + name);
295 const char *Interpreter::GetPath(const std::string &name) const {
296 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
297 if (i != parsedDefinitions.end()) {
298 if (i->second.type == PATH) {
299 return strings[i->second.index];
301 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Path");
304 throw Error("access to undefined Path " + name);
308 Spell *Interpreter::GetSpell(const std::string &name) {
309 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
310 if (i != parsedDefinitions.end()) {
311 if (i->second.type == SPELL) {
312 return spells[i->second.index];
314 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Spell");
317 throw Error("access to undefined Spell " + name);
321 Sprite *Interpreter::GetSprite(const std::string &name) {
322 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
323 if (i != parsedDefinitions.end()) {
324 if (i->second.type == SPRITE) {
325 return sprites[i->second.index];
327 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Sprite");
330 throw Error("access to undefined Sprite " + name);
334 const char *Interpreter::GetString(const std::string &name) const {
335 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
336 if (i != parsedDefinitions.end()) {
337 // TODO: enable path to string casting some time
338 if (i->second.type == STRING /* || i->second.type == PATH */) {
339 return strings[i->second.index];
341 throw Error("cannot cast " + i->second.dfn->TypeName() + " to String");
344 throw Error("access to undefined String " + name);
348 TargetingMode *Interpreter::GetTargetingMode(const std::string &name) {
349 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
350 if (i != parsedDefinitions.end()) {
351 if (i->second.type == TARGETING_MODE) {
352 return targetingModes[i->second.index];
354 throw Error("cannot cast " + i->second.dfn->TypeName() + " to TargetingMode");
357 throw Error("access to undefined TargetingMode " + name);
361 Vector<int> Interpreter::GetVector(const std::string &name) const {
362 map<string, ParsedDefinition>::const_iterator i(parsedDefinitions.find(name));
363 if (i != parsedDefinitions.end()) {
364 if (i->second.type == VECTOR) {
365 return vectors[i->second.index];
367 throw Error("cannot cast " + i->second.dfn->TypeName() + " to Vector");
370 throw Error("access to undefined Vector " + name);
375 void Interpreter::ReadSource() {
376 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
377 ReadDefinition(source.GetDefinition(*i));
381 void Interpreter::ReadDefinition(const Definition &dfn) {
382 if (parsedDefinitions.find(dfn.Identifier()) != parsedDefinitions.end()) {
385 if (dfn.HasLiteralValue()) {
392 void Interpreter::ReadLiteral(const Definition &dfn) {
393 switch (dfn.GetLiteral()->GetType()) {
394 case Literal::ARRAY_VALUES:
395 valueArrays.push_back(dfn.GetLiteral()->GetValues());
396 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VALUE_ARRAY, valueArrays.size() - 1)));
398 case Literal::ARRAY_PROPS:
399 propertyListArrays.push_back(dfn.GetLiteral()->GetPropertyLists());
400 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PROPERTY_LIST_ARRAY, propertyListArrays.size() - 1)));
402 case Literal::BOOLEAN:
403 booleans.push_back(dfn.GetLiteral()->GetBoolean());
404 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BOOLEAN, booleans.size() - 1)));
407 colors.push_back(Color(dfn.GetLiteral()->GetRed(), dfn.GetLiteral()->GetGreen(), dfn.GetLiteral()->GetBlue(), dfn.GetLiteral()->GetAlpha()));
408 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COLOR, colors.size() - 1)));
410 case Literal::NUMBER:
411 numbers.push_back(dfn.GetLiteral()->GetNumber());
412 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1)));
416 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
417 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
418 str[dfn.GetLiteral()->GetString().size()] = '\0';
419 strings.push_back(str);
421 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PATH, strings.size() - 1)));
423 case Literal::STRING:
425 char *str(new char[dfn.GetLiteral()->GetString().size() + 1]);
426 std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size());
427 str[dfn.GetLiteral()->GetString().size()] = '\0';
428 strings.push_back(str);
430 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, STRING, strings.size() - 1)));
432 case Literal::VECTOR:
433 vectors.push_back(Vector<int>(dfn.GetLiteral()->GetX(), dfn.GetLiteral()->GetY()));
434 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, VECTOR, vectors.size() - 1)));
436 case Literal::OBJECT:
442 Animation *Interpreter::GetAnimation(const Value &v) {
444 if (v.GetLiteral().GetTypeName() == "ComplexAnimation") {
445 ComplexAnimation *a(new ComplexAnimation);
446 ReadComplexAnimation(*a, *v.GetLiteral().GetProperties());
447 complexAnimations.push_back(a);
450 SimpleAnimation *a(new SimpleAnimation);
451 ReadSimpleAnimation(*a, *v.GetLiteral().GetProperties());
452 simpleAnimations.push_back(a);
456 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
457 return GetAnimation(v.GetIdentifier());
461 battle::Resources *Interpreter::GetBattleResources(const Value &v) {
463 battle::Resources *r(new battle::Resources);
464 ReadBattleResources(*r, *v.GetLiteral().GetProperties());
467 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
468 return GetBattleResources(v.GetIdentifier());
472 bool Interpreter::GetBoolean(const Value &v) {
474 return v.GetLiteral().GetBoolean();
476 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
477 return GetBoolean(v.GetIdentifier());
481 Color Interpreter::GetColor(const Value &v) {
483 return Color(v.GetLiteral().GetRed(), v.GetLiteral().GetGreen(), v.GetLiteral().GetBlue(), v.GetLiteral().GetAlpha());
485 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
486 return GetColor(v.GetIdentifier());
490 Font *Interpreter::GetFont(const Value &v) {
493 ReadFont(*f, *v.GetLiteral().GetProperties());
496 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
497 return GetFont(v.GetIdentifier());
501 Frame *Interpreter::GetFrame(const Value &v) {
504 ReadFrame(*f, *v.GetLiteral().GetProperties());
507 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
508 return GetFrame(v.GetIdentifier());
512 Gauge *Interpreter::GetGauge(const Value &v) {
515 ReadGauge(*g, *v.GetLiteral().GetProperties());
518 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
519 return GetGauge(v.GetIdentifier());
523 Hero *Interpreter::GetHero(const Value &v) {
526 ReadHero(*h, *v.GetLiteral().GetProperties());
529 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
530 return GetHero(v.GetIdentifier());
534 Ikari *Interpreter::GetIkari(const Value &v) {
537 ReadIkari(*i, *v.GetLiteral().GetProperties());
540 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
541 return GetIkari(v.GetIdentifier());
545 SDL_Surface *Interpreter::GetImage(const Value &v) {
546 string path(GetPath(v));
547 map<string, SDL_Surface *>::const_iterator i(imageCache.find(path));
548 if (i == imageCache.end()) {
549 SDL_Surface *image(IMG_Load(path.c_str()));
550 images.push_back(image);
551 imageCache.insert(make_pair(path, image));
558 Item *Interpreter::GetItem(const Value &v) {
561 ReadItem(*i, *v.GetLiteral().GetProperties());
564 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
565 return GetItem(v.GetIdentifier());
569 graphics::MenuProperties *Interpreter::GetMenuProperties(const Value &v) {
571 graphics::MenuProperties *m(new graphics::MenuProperties);
572 ReadMenuProperties(*m, *v.GetLiteral().GetProperties());
575 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
576 return GetMenuProperties(v.GetIdentifier());
580 Monster *Interpreter::GetMonster(const Value &v) {
582 Monster *m(new Monster);
583 ReadMonster(*m, *v.GetLiteral().GetProperties());
586 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
587 return GetMonster(v.GetIdentifier());
591 int Interpreter::GetNumber(const Value &v) {
593 return v.GetLiteral().GetNumber();
595 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
596 return GetNumber(v.GetIdentifier());
600 PartyLayout *Interpreter::GetPartyLayout(const Value &v) {
602 PartyLayout *l(new PartyLayout);
603 ReadPartyLayout(*l, *v.GetLiteral().GetProperties());
606 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
607 return GetPartyLayout(v.GetIdentifier());
611 const char *Interpreter::GetPath(const Value &v) {
613 return v.GetLiteral().GetString().c_str();
615 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
616 return GetPath(v.GetIdentifier());
620 const PropertyList *Interpreter::GetPropertyList(const Value &v) {
622 return v.GetLiteral().GetProperties();
624 throw Error("cannot reference property lists");
628 const vector<PropertyList *> &Interpreter::GetPropertyListArray(const Value &v) {
630 return v.GetLiteral().GetPropertyLists();
632 throw Error("cannot reference property list arrays");
636 Spell *Interpreter::GetSpell(const Value &v) {
639 ReadSpell(*s, *v.GetLiteral().GetProperties());
642 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
643 return GetSpell(v.GetIdentifier());
647 Sprite *Interpreter::GetSprite(const Value &v) {
649 Sprite *s(new Sprite);
650 ReadSprite(*s, *v.GetLiteral().GetProperties());
653 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
654 return GetSprite(v.GetIdentifier());
658 const char *Interpreter::GetString(const Value &v) {
660 return v.GetLiteral().GetString().c_str();
662 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
663 return GetString(v.GetIdentifier());
667 TargetingMode *Interpreter::GetTargetingMode(const Value &v) {
669 TargetingMode *t(new TargetingMode);
670 ReadTargetingMode(*t, *v.GetLiteral().GetProperties());
673 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
674 return GetTargetingMode(v.GetIdentifier());
678 Vector<int> Interpreter::GetVector(const Value &v) {
680 return Vector<int>(v.GetLiteral().GetX(), v.GetLiteral().GetY());
682 ReadDefinition(source.GetDefinition(v.GetIdentifier()));
683 return GetVector(v.GetIdentifier());
687 const vector<Value *> &Interpreter::GetValueArray(const Value &v) {
689 return v.GetLiteral().GetValues();
691 throw Error("cannot reference value arrays");
696 void Interpreter::ReadObject(const Definition &dfn) {
697 if (dfn.TypeName() == "BattleResources") {
698 battle::Resources *res(new battle::Resources);
699 int index(battleResources.size());
700 battleResources.push_back(res);
701 ReadBattleResources(*res, *dfn.GetProperties());
702 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, BATTLE_RESOURCES, index)));
703 } else if (dfn.TypeName() == "ComplexAnimation") {
704 ComplexAnimation *animation(new ComplexAnimation);
705 int index(complexAnimations.size());
706 complexAnimations.push_back(animation);
707 ReadComplexAnimation(*animation, *dfn.GetProperties());
708 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, COMPLEX_ANIMATION, index)));
709 } else if (dfn.TypeName() == "Font") {
710 Font *font(new Font);
711 int index(fonts.size());
712 fonts.push_back(font);
713 ReadFont(*font, *dfn.GetProperties());
714 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FONT, index)));
715 } else if (dfn.TypeName() == "Frame") {
716 Frame *frame(new Frame);
717 int index(frames.size());
718 frames.push_back(frame);
719 ReadFrame(*frame, *dfn.GetProperties());
720 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, FRAME, index)));
721 } else if (dfn.TypeName() == "Gauge") {
722 Gauge *gauge(new Gauge);
723 int index(gauges.size());
724 gauges.push_back(gauge);
725 ReadGauge(*gauge, *dfn.GetProperties());
726 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, GAUGE, index)));
727 } else if (dfn.TypeName() == "Hero") {
728 Hero *hero(new Hero);
729 int index(heroes.size());
730 heroes.push_back(hero);
731 ReadHero(*hero, *dfn.GetProperties());
732 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, HERO, index)));
733 } else if (dfn.TypeName() == "Ikari") {
734 Ikari *ikari(new Ikari);
735 int index(ikaris.size());
736 ikaris.push_back(ikari);
737 ReadIkari(*ikari, *dfn.GetProperties());
738 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, IKARI, index)));
739 } else if (dfn.TypeName() == "Item") {
740 Item *item(new Item);
741 int index(items.size());
742 items.push_back(item);
743 ReadItem(*item, *dfn.GetProperties());
744 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, ITEM, index)));
745 } else if (dfn.TypeName() == "MenuProperties") {
746 graphics::MenuProperties *mprops(new graphics::MenuProperties);
747 int index(menuProperties.size());
748 menuProperties.push_back(mprops);
749 ReadMenuProperties(*mprops, *dfn.GetProperties());
750 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MENU_PROPERTIES, index)));
751 } else if (dfn.TypeName() == "Monster") {
752 Monster *monster(new Monster);
753 int index(monsters.size());
754 monsters.push_back(monster);
755 ReadMonster(*monster, *dfn.GetProperties());
756 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, MONSTER, index)));
757 } else if (dfn.TypeName() == "PartyLayout") {
758 PartyLayout *layout(new PartyLayout);
759 int index(partyLayouts.size());
760 partyLayouts.push_back(layout);
761 ReadPartyLayout(*layout, *dfn.GetProperties());
762 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PARTY_LAYOUT, index)));
763 } else if (dfn.TypeName() == "SimpleAnimation") {
764 SimpleAnimation *animation(new SimpleAnimation);
765 int index(simpleAnimations.size());
766 simpleAnimations.push_back(animation);
767 ReadSimpleAnimation(*animation, *dfn.GetProperties());
768 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SIMPLE_ANIMATION, index)));
769 } else if (dfn.TypeName() == "Spell") {
770 Spell *spell(new Spell);
771 int index(spells.size());
772 spells.push_back(spell);
773 ReadSpell(*spell, *dfn.GetProperties());
774 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPELL, index)));
775 } else if (dfn.TypeName() == "Sprite") {
776 Sprite *sprite(new Sprite);
777 int index(sprites.size());
778 sprites.push_back(sprite);
779 ReadSprite(*sprite, *dfn.GetProperties());
780 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, SPRITE, index)));
781 } else if (dfn.TypeName() == "TargetingMode") {
782 TargetingMode *mode(new TargetingMode);
783 int index(targetingModes.size());
784 targetingModes.push_back(mode);
785 ReadTargetingMode(*mode, *dfn.GetProperties());
786 parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, TARGETING_MODE, index)));
788 throw Error("unhandled object type: " + dfn.TypeName());
793 void Interpreter::ReadBattleResources(battle::Resources &res, const PropertyList &props) {
794 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
795 if (i->first == "swapCursor") {
796 res.swapCursor = GetSprite(*i->second);
797 } else if (i->first == "moveIcons") {
798 res.moveIcons = GetSprite(*i->second);
799 } else if (i->first == "attackIcons") {
800 res.attackIcons = GetSprite(*i->second);
801 } else if (i->first == "attackChoiceIcons") {
802 res.attackChoiceIcons = GetSprite(*i->second);
803 } else if (i->first == "titleFrame") {
804 res.titleFrame = GetFrame(*i->second);
805 } else if (i->first == "titleFont") {
806 res.titleFont = GetFont(*i->second);
807 } else if (i->first == "heroTagFrame") {
808 res.heroTagFrame = GetFrame(*i->second);
809 } else if (i->first == "activeHeroTagFrame") {
810 res.activeHeroTagFrame = GetFrame(*i->second);
811 } else if (i->first == "smallHeroTagFrame") {
812 res.smallHeroTagFrame = GetFrame(*i->second);
813 } else if (i->first == "lastSmallHeroTagFrame") {
814 res.lastSmallHeroTagFrame = GetFrame(*i->second);
815 } else if (i->first == "heroTagFont") {
816 res.heroTagFont = GetFont(*i->second);
817 } else if (i->first == "heroTagLabels") {
818 res.heroTagLabels = GetSprite(*i->second);
819 } else if (i->first == "healthGauge") {
820 res.healthGauge = GetGauge(*i->second);
821 } else if (i->first == "manaGauge") {
822 res.manaGauge = GetGauge(*i->second);
823 } else if (i->first == "ikariGauge") {
824 res.ikariGauge = GetGauge(*i->second);
825 } else if (i->first == "selectFrame") {
826 res.selectFrame = GetFrame(*i->second);
827 } else if (i->first == "normalFont") {
828 res.normalFont = GetFont(*i->second);
829 } else if (i->first == "disabledFont") {
830 res.disabledFont = GetFont(*i->second);
831 } else if (i->first == "menuCursor") {
832 res.menuCursor = GetSprite(*i->second);
833 } else if (i->first == "weaponTargetCursor") {
834 res.weaponTargetCursor = GetSprite(*i->second);
835 } else if (i->first == "magicTargetCursor") {
836 res.magicTargetCursor = GetSprite(*i->second);
837 } else if (i->first == "itemTargetCursor") {
838 res.itemTargetCursor = GetSprite(*i->second);
839 } else if (i->first == "spellMenuHeadline") {
840 res.spellMenuHeadline = GetString(*i->second);
841 } else if (i->first == "spellMenuProperties") {
842 res.spellMenuProperties = GetMenuProperties(*i->second);
843 } else if (i->first == "itemMenuHeadline") {
844 res.itemMenuHeadline = GetString(*i->second);
845 } else if (i->first == "itemMenuProperties") {
846 res.itemMenuProperties = GetMenuProperties(*i->second);
847 } else if (i->first == "ikariMenuHeadline") {
848 res.ikariMenuHeadline = GetString(*i->second);
849 } else if (i->first == "ikariMenuProperties") {
850 res.ikariMenuProperties = GetMenuProperties(*i->second);
851 } else if (i->first == "noEquipmentText") {
852 res.noEquipmentText = GetString(*i->second);
853 } else if (i->first == "escapeText") {
854 res.escapeText = GetString(*i->second);
855 } else if (i->first == "numberAnimationPrototype") {
856 res.numberAnimationPrototype = GetAnimation(*i->second);
857 } else if (i->first == "bigNumberSprite") {
858 res.bigNumberSprite = GetSprite(*i->second);
859 } else if (i->first == "greenNumberSprite") {
860 res.greenNumberSprite = GetSprite(*i->second);
861 } else if (i->first == "weaponMenuIcon") {
862 res.weaponMenuIcon = GetSprite(*i->second);
863 } else if (i->first == "armorMenuIcon") {
864 res.armorMenuIcon = GetSprite(*i->second);
865 } else if (i->first == "shieldMenuIcon") {
866 res.shieldMenuIcon = GetSprite(*i->second);
867 } else if (i->first == "helmetMenuIcon") {
868 res.helmetMenuIcon = GetSprite(*i->second);
869 } else if (i->first == "ringMenuIcon") {
870 res.ringMenuIcon = GetSprite(*i->second);
871 } else if (i->first == "jewelMenuIcon") {
872 res.jewelMenuIcon = GetSprite(*i->second);
873 } else if (i->first == "levelLabelCol") {
874 res.levelLabelCol = GetNumber(*i->second);
875 } else if (i->first == "levelLabelRow") {
876 res.levelLabelRow = GetNumber(*i->second);
877 } else if (i->first == "healthLabelCol") {
878 res.healthLabelCol = GetNumber(*i->second);
879 } else if (i->first == "healthLabelRow") {
880 res.healthLabelRow = GetNumber(*i->second);
881 } else if (i->first == "manaLabelCol") {
882 res.manaLabelCol = GetNumber(*i->second);
883 } else if (i->first == "manaLabelRow") {
884 res.manaLabelRow = GetNumber(*i->second);
885 } else if (i->first == "moveLabelCol") {
886 res.moveLabelCol = GetNumber(*i->second);
887 } else if (i->first == "moveLabelRow") {
888 res.moveLabelRow = GetNumber(*i->second);
889 } else if (i->first == "ikariLabelCol") {
890 res.ikariLabelCol = GetNumber(*i->second);
891 } else if (i->first == "ikariLabelRow") {
892 res.ikariLabelRow = GetNumber(*i->second);
893 } else if (i->first == "heroesBgColor") {
894 res.heroesBgColor = GetColor(*i->second);
896 throw Error("unknown BattleResources property: " + i->first);
901 void Interpreter::ReadComplexAnimation(ComplexAnimation &a, const PropertyList &props) {
902 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
903 if (i->first == "sprite") {
904 a.SetSprite(GetSprite(*i->second));
905 } else if (i->first == "frametime") {
906 a.SetFrameTime(GetNumber(*i->second));
907 } else if (i->first == "repeat") {
908 a.SetRepeat(GetBoolean(*i->second));
909 } else if (i->first == "frames") {
910 const vector<PropertyList *> &values(GetPropertyListArray(*i->second));
911 for (vector<PropertyList *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
912 ComplexAnimation::FrameProp frame;
913 ReadComplexAnimationFrame(frame, **i);
917 throw Error("unknown ComplexAnimation property: " + i->first);
922 void Interpreter::ReadComplexAnimationFrame(ComplexAnimation::FrameProp &f, const PropertyList &props) {
923 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
924 if (i->first == "column") {
925 f.col = GetNumber(*i->second);
926 } else if (i->first == "row") {
927 f.row = GetNumber(*i->second);
928 } else if (i->first == "disposition") {
929 f.disposition = GetVector(*i->second);
931 throw Error("unknown ComplexAnimationFrame property: " + i->first);
936 void Interpreter::ReadFont(Font &f, const PropertyList &props) {
937 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
938 if (i->first == "sprite") {
939 f.SetSprite(GetSprite(*i->second));
940 } else if (i->first == "columnoffset") {
941 f.SetColOffset(GetNumber(*i->second));
942 } else if (i->first == "rowoffset") {
943 f.SetRowOffset(GetNumber(*i->second));
945 throw Error("unknown Font property: " + i->first);
950 void Interpreter::ReadFrame(Frame &f, const PropertyList &props) {
951 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
952 if (i->first == "image") {
953 f.SetSurface(GetImage(*i->second));
954 } else if (i->first == "border") {
955 f.SetBorderSize(GetVector(*i->second));
956 } else if (i->first == "repeat") {
957 f.SetRepeatSize(GetVector(*i->second));
958 } else if (i->first == "offset") {
959 f.SetOffset(GetVector(*i->second));
961 throw Error("unknown Frame property: " + i->first);
966 void Interpreter::ReadGauge(Gauge &g, const PropertyList &props) {
967 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
968 if (i->first == "image") {
969 g.SetSurface(GetImage(*i->second));
970 } else if (i->first == "full") {
971 g.SetFullOffset(GetVector(*i->second));
972 } else if (i->first == "empty") {
973 g.SetEmptyOffset(GetVector(*i->second));
974 } else if (i->first == "height") {
975 g.SetHeight(GetNumber(*i->second));
976 } else if (i->first == "start") {
977 g.SetStartWidth(GetNumber(*i->second));
978 } else if (i->first == "repeat") {
979 g.SetRepeatWidth(GetNumber(*i->second));
980 } else if (i->first == "end") {
981 g.SetEndWidth(GetNumber(*i->second));
983 throw Error("unknown Gauge property: " + i->first);
988 void Interpreter::ReadIkari(Ikari &ikari, const PropertyList &props) {
989 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
990 if (i->first == "name") {
991 ikari.SetName(GetString(*i->second));
992 } else if (i->first == "cost") {
993 ikari.SetCost(GetNumber(*i->second));
994 } else if (i->first == "targets") {
995 ikari.GetTargetingMode() = *GetTargetingMode(*i->second);
996 } else if (i->first == "magical") {
997 if (GetBoolean(*i->second)) {
1000 } else if (i->first == "physical") {
1001 if (GetBoolean(*i->second)) {
1002 ikari.SetPhysical();
1005 throw Error("unknown Ikari property: " + i->first);
1010 void Interpreter::ReadItem(Item &item, const PropertyList &props) {
1011 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1012 if (i->first == "name") {
1013 item.SetName(GetString(*i->second));
1014 } else if (i->first == "menuicon") {
1015 item.SetMenuIcon(GetSprite(*i->second));
1016 } else if (i->first == "battle") {
1017 if (GetBoolean(*i->second)) {
1018 item.SetUsableInBattle();
1020 } else if (i->first == "targets") {
1021 item.GetTargetingMode() = *GetTargetingMode(*i->second);
1022 } else if (i->first == "ikari") {
1023 item.SetIkari(GetIkari(*i->second));
1024 } else if (i->first == "attackanimation") {
1025 item.SetAttackAnimation(GetAnimation(*i->second));
1027 throw Error("unknown Item property: " + i->first);
1032 void Interpreter::ReadHero(Hero &h, const PropertyList &props) {
1033 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1034 if (i->first == "name") {
1035 h.SetName(GetString(*i->second));
1036 } else if (i->first == "sprite") {
1037 h.SetSprite(GetSprite(*i->second));
1038 } else if (i->first == "level") {
1039 h.SetLevel(GetNumber(*i->second));
1040 } else if (i->first == "maxHealth") {
1041 h.SetMaxHealth(GetNumber(*i->second));
1042 } else if (i->first == "health") {
1043 h.SetHealth(GetNumber(*i->second));
1044 } else if (i->first == "maxMana") {
1045 h.SetMaxMana(GetNumber(*i->second));
1046 } else if (i->first == "mana") {
1047 h.SetMana(GetNumber(*i->second));
1048 } else if (i->first == "ip") {
1049 h.SetIP(GetNumber(*i->second));
1050 } else if (i->first == "stats") {
1051 battle::Stats stats;
1052 ReadStats(stats, *GetPropertyList(*i->second));
1054 } else if (i->first == "attackAnimation") {
1055 h.SetAttackAnimation(GetAnimation(*i->second));
1056 } else if (i->first == "spellAnimation") {
1057 h.SetSpellAnimation(GetAnimation(*i->second));
1058 } else if (i->first == "meleeAnimation") {
1059 h.SetMeleeAnimation(GetAnimation(*i->second));
1061 throw Error("unknown Hero property: " + i->first);
1066 void Interpreter::ReadMenuProperties(graphics::MenuProperties &mprops, const PropertyList &props) {
1067 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1068 if (i->first == "font") {
1069 mprops.font = GetFont(*i->second);
1070 } else if (i->first == "disabledFont") {
1071 mprops.disabledFont = GetFont(*i->second);
1072 } else if (i->first == "cursor") {
1073 mprops.cursor = GetSprite(*i->second);
1074 } else if (i->first == "charsPerEntry") {
1075 mprops.charsPerEntry = GetNumber(*i->second);
1076 } else if (i->first == "rows") {
1077 mprops.rows = GetNumber(*i->second);
1078 } else if (i->first == "rowGap") {
1079 mprops.rowGap = GetNumber(*i->second);
1080 } else if (i->first == "iconSpace") {
1081 mprops.iconSpace = GetNumber(*i->second);
1082 } else if (i->first == "cols") {
1083 mprops.cols = GetNumber(*i->second);
1084 } else if (i->first == "colGap") {
1085 mprops.colGap = GetNumber(*i->second);
1086 } else if (i->first == "delimiter") {
1087 mprops.delimiter = *GetString(*i->second);
1088 } else if (i->first == "charsPerNumber") {
1089 mprops.charsPerNumber = GetNumber(*i->second);
1090 } else if (i->first == "charsPerAdditionalText") {
1091 mprops.charsPerAdditionalText = GetNumber(*i->second);
1092 } else if (i->first == "additionalTextGap") {
1093 mprops.additionalTextGap = GetNumber(*i->second);
1095 throw Error("unknown MenuProperties property: " + i->first);
1100 void Interpreter::ReadMonster(Monster &m, const PropertyList &props) {
1101 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1102 if (i->first == "name") {
1103 m.SetName(GetString(*i->second));
1104 } else if (i->first == "sprite") {
1105 m.SetSprite(GetSprite(*i->second));
1106 } else if (i->first == "level") {
1107 m.SetLevel(GetNumber(*i->second));
1108 } else if (i->first == "maxHealth") {
1109 m.SetMaxHealth(GetNumber(*i->second));
1110 } else if (i->first == "health") {
1111 m.SetHealth(GetNumber(*i->second));
1112 } else if (i->first == "maxMana") {
1113 m.SetMaxMana(GetNumber(*i->second));
1114 } else if (i->first == "mana") {
1115 m.SetMana(GetNumber(*i->second));
1116 } else if (i->first == "stats") {
1117 battle::Stats stats;
1118 ReadStats(stats, *GetPropertyList(*i->second));
1120 } else if (i->first == "attackAnimation") {
1121 m.SetAttackAnimation(GetAnimation(*i->second));
1122 } else if (i->first == "meleeAnimation") {
1123 m.SetMeleeAnimation(GetAnimation(*i->second));
1125 throw Error("unknown Monster property: " + i->first);
1130 void Interpreter::ReadPartyLayout(PartyLayout &p, const PropertyList &props) {
1131 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1132 if (i->first == "positions") {
1133 const vector<Value *> &positions(GetValueArray(*i->second));
1134 for (vector<Value *>::const_iterator j(positions.begin()), end(positions.end()); j != end; ++j) {
1135 p.AddPosition(GetVector(**j));
1138 throw Error("unknown PartyLayout property: " + i->first);
1143 void Interpreter::ReadSimpleAnimation(SimpleAnimation &a, const PropertyList &props) {
1144 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1145 if (i->first == "sprite") {
1146 a.SetSprite(GetSprite(*i->second));
1147 } else if (i->first == "frametime") {
1148 a.SetFrameTime(GetNumber(*i->second));
1149 } else if (i->first == "repeat") {
1150 a.SetRepeat(GetBoolean(*i->second));
1151 } else if (i->first == "framecount") {
1152 a.SetNumFrames(GetNumber(*i->second));
1153 } else if (i->first == "col") {
1154 a.SetCol(GetNumber(*i->second));
1155 } else if (i->first == "row") {
1156 a.SetRow(GetNumber(*i->second));
1158 throw Error("unknown SimpleAnimation property: " + i->first);
1163 void Interpreter::ReadSpell(Spell &s, const PropertyList &props) {
1164 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1165 if (i->first == "name") {
1166 s.SetName(GetString(*i->second));
1167 } else if (i->first == "cost") {
1168 s.SetCost(GetNumber(*i->second));
1169 } else if (i->first == "battle") {
1170 if (GetBoolean(*i->second)) {
1171 s.SetUsableInBattle();
1173 } else if (i->first == "targets") {
1174 s.GetTargetingMode() = *GetTargetingMode(*i->second);
1176 throw Error("unknown Spell property: " + i->first);
1181 void Interpreter::ReadSprite(Sprite &s, const PropertyList &props) {
1182 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1183 if (i->first == "image") {
1184 s.SetSurface(GetImage(*i->second));
1185 } else if (i->first == "size") {
1186 s.SetSize(GetVector(*i->second));
1187 } else if (i->first == "offset") {
1188 s.SetOffset(GetVector(*i->second));
1190 throw Error("unknown Sprite property: " + i->first);
1195 void Interpreter::ReadStats(Stats &s, const PropertyList &props) {
1196 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1197 if (i->first == "atp") {
1198 s.SetAttack(GetNumber(*i->second));
1199 } else if (i->first == "dfp") {
1200 s.SetDefense(GetNumber(*i->second));
1201 } else if (i->first == "str") {
1202 s.SetStrength(GetNumber(*i->second));
1203 } else if (i->first == "agl") {
1204 s.SetAgility(GetNumber(*i->second));
1205 } else if (i->first == "int") {
1206 s.SetIntelligence(GetNumber(*i->second));
1207 } else if (i->first == "gut") {
1208 s.SetGut(GetNumber(*i->second));
1209 } else if (i->first == "mgr") {
1210 s.SetMagicResistance(GetNumber(*i->second));
1212 throw Error("unknown Stats property: " + i->first);
1217 void Interpreter::ReadTargetingMode(TargetingMode &t, const PropertyList &props) {
1218 for (PropertyList::ConstIterator i(props.Begin()), end(props.End()); i != end; ++i) {
1219 if (i->first == "ally") {
1220 if (GetBoolean(*i->second)) {
1225 } else if (i->first == "enemy") {
1226 if (GetBoolean(*i->second)) {
1231 } else if (i->first == "all") {
1232 if (GetBoolean(*i->second)) {
1235 } else if (i->first == "multiple") {
1236 if (GetBoolean(*i->second)) {
1239 } else if (i->first == "single") {
1240 if (GetBoolean(*i->second)) {
1244 throw Error("unknown TargetingMode property: " + i->first);