00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "resources/monsterdb.h"
00023
00024 #include "resources/monsterinfo.h"
00025
00026 #include "log.h"
00027
00028 #include "utils/dtor.h"
00029 #include "utils/gettext.h"
00030 #include "utils/xml.h"
00031
00032 namespace
00033 {
00034 MonsterDB::MonsterInfos mMonsterInfos;
00035 MonsterInfo mUnknown;
00036 bool mLoaded = false;
00037 }
00038
00039 void MonsterDB::load()
00040 {
00041 if (mLoaded)
00042 return;
00043
00044 mUnknown.addSprite("error.xml");
00045 mUnknown.setName(_("unnamed"));
00046
00047 logger->log("Initializing monster database...");
00048
00049 XML::Document doc(_("monsters.xml"));
00050 xmlNodePtr rootNode = doc.rootNode();
00051
00052 if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters"))
00053 {
00054 logger->error("Monster Database: Error while loading monster.xml!");
00055 }
00056
00057
00058 for_each_xml_child_node(monsterNode, rootNode)
00059 {
00060 if (!xmlStrEqual(monsterNode->name, BAD_CAST "monster"))
00061 {
00062 continue;
00063 }
00064
00065 MonsterInfo *currentInfo = new MonsterInfo;
00066
00067 currentInfo->setName(XML::getProperty(monsterNode, "name", _("unnamed")));
00068
00069 std::string targetCursor;
00070 targetCursor = XML::getProperty(monsterNode, "targetCursor", "medium");
00071 if (targetCursor == "small")
00072 {
00073 currentInfo->setTargetCursorSize(Being::TC_SMALL);
00074 }
00075 else if (targetCursor == "medium")
00076 {
00077 currentInfo->setTargetCursorSize(Being::TC_MEDIUM);
00078 }
00079 else if (targetCursor == "large")
00080 {
00081 currentInfo->setTargetCursorSize(Being::TC_LARGE);
00082 }
00083 else
00084 {
00085 logger->log("MonsterDB: Unknown target cursor type \"%s\" for %s -"
00086 "using medium sized one",
00087 targetCursor.c_str(), currentInfo->getName().c_str());
00088 currentInfo->setTargetCursorSize(Being::TC_MEDIUM);
00089 }
00090
00091
00092 for_each_xml_child_node(spriteNode, monsterNode)
00093 {
00094 if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
00095 {
00096 currentInfo->addSprite(
00097 (const char*) spriteNode->xmlChildrenNode->content);
00098 }
00099 else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
00100 {
00101 std::string event = XML::getProperty(spriteNode, "event", "");
00102 const char *filename;
00103 filename = (const char*) spriteNode->xmlChildrenNode->content;
00104
00105 if (event == "hit")
00106 {
00107 currentInfo->addSound(MONSTER_EVENT_HIT, filename);
00108 }
00109 else if (event == "miss")
00110 {
00111 currentInfo->addSound(MONSTER_EVENT_MISS, filename);
00112 }
00113 else if (event == "hurt")
00114 {
00115 currentInfo->addSound(MONSTER_EVENT_HURT, filename);
00116 }
00117 else if (event == "die")
00118 {
00119 currentInfo->addSound(MONSTER_EVENT_DIE, filename);
00120 }
00121 else
00122 {
00123 logger->log("MonsterDB: Warning, sound effect %s for "
00124 "unknown event %s of monster %s",
00125 filename, event.c_str(),
00126 currentInfo->getName().c_str());
00127 }
00128 }
00129 else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
00130 {
00131 const int id = XML::getProperty(spriteNode, "id", 0);
00132 const std::string particleEffect = XML::getProperty(
00133 spriteNode, "particle-effect", "");
00134 SpriteAction spriteAction = SpriteDef::makeSpriteAction(
00135 XML::getProperty(spriteNode, "action", "attack"));
00136 currentInfo->addMonsterAttack(id, particleEffect, spriteAction);
00137 }
00138 else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
00139 {
00140 currentInfo->addParticleEffect(
00141 (const char*) spriteNode->xmlChildrenNode->content);
00142 }
00143 }
00144 mMonsterInfos[XML::getProperty(monsterNode, "id", 0)] = currentInfo;
00145 }
00146
00147 mLoaded = true;
00148 }
00149
00150 void MonsterDB::unload()
00151 {
00152 delete_all(mMonsterInfos);
00153 mMonsterInfos.clear();
00154
00155 mLoaded = false;
00156 }
00157
00158
00159 const MonsterInfo &MonsterDB::get(int id)
00160 {
00161 MonsterInfoIterator i = mMonsterInfos.find(id);
00162
00163 if (i == mMonsterInfos.end())
00164 {
00165 logger->log("MonsterDB: Warning, unknown monster ID %d requested", id);
00166 return mUnknown;
00167 }
00168 else
00169 {
00170 return *(i->second);
00171 }
00172 }