summaryrefslogtreecommitdiffstats
path: root/src/game-server/monstermanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/monstermanager.cpp')
-rw-r--r--src/game-server/monstermanager.cpp453
1 files changed, 225 insertions, 228 deletions
diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp
index bb29bab..3a9d791 100644
--- a/src/game-server/monstermanager.cpp
+++ b/src/game-server/monstermanager.cpp
@@ -26,7 +26,6 @@
#include "game-server/itemmanager.h"
#include "game-server/monster.h"
#include "utils/logger.h"
-#include "utils/xml.h"
#define MAX_MUTATION 99
#define DEFAULT_MONSTER_SIZE 16
@@ -40,278 +39,276 @@ void MonsterManager::reload()
void MonsterManager::initialize()
{
- XML::Document doc(mMonsterReferenceFile);
- xmlNodePtr rootNode = doc.rootNode();
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters"))
+}
+
+void MonsterManager::deinitialize()
+{
+ for (MonsterClasses::iterator i = mMonsterClasses.begin(),
+ i_end = mMonsterClasses.end(); i != i_end; ++i)
+ {
+ delete i->second;
+ }
+ mMonsterClasses.clear();
+ mMonsterClassesByName.clear();
+}
+
+MonsterClass *MonsterManager::getMonsterByName(const std::string &name) const
+{
+ return mMonsterClassesByName.value(name);
+}
+
+MonsterClass *MonsterManager::getMonster(int id) const
+{
+ MonsterClasses::const_iterator i = mMonsterClasses.find(id);
+ return i != mMonsterClasses.end() ? i->second : 0;
+}
+
+/**
+ * Read a <monster> element from settings.
+ * Used by SettingsManager.
+ */
+void MonsterManager::readMonsterNode(xmlNodePtr node, const std::string &filename)
+{
+ if (!xmlStrEqual(node->name, BAD_CAST "monster"))
+ return;
+
+ int id = XML::getProperty(node, "id", 0);
+ std::string name = XML::getProperty(node, "name", std::string());
+
+ if (id < 1)
{
- LOG_ERROR("Monster Manager: Error while parsing monster database ("
- << mMonsterReferenceFile << ")!");
+ LOG_WARN("Monster Manager: Ignoring monster ("
+ << name << ") without Id in "
+ << filename << "! It has been ignored.");
return;
}
- LOG_INFO("Loading monster reference: " << mMonsterReferenceFile);
- int nbMonsters = 0;
- for_each_xml_child_node(node, rootNode)
+ MonsterClasses::iterator i = mMonsterClasses.find(id);
+ if (i != mMonsterClasses.end())
{
- if (!xmlStrEqual(node->name, BAD_CAST "monster"))
- continue;
+ LOG_WARN("Monster Manager: Ignoring duplicate definition of "
+ "monster '" << id << "'!");
+ return;
+ }
- int id = XML::getProperty(node, "id", 0);
- std::string name = XML::getProperty(node, "name", std::string());
+ MonsterClass *monster = new MonsterClass(id);
+ mMonsterClasses[id] = monster;
- if (id < 1)
- {
- LOG_WARN("Monster Manager: Ignoring monster ("
- << name << ") without Id in "
- << mMonsterReferenceFile << "! It has been ignored.");
- continue;
- }
+ if (!name.empty())
+ {
+ monster->setName(name);
- MonsterClasses::iterator i = mMonsterClasses.find(id);
- if (i != mMonsterClasses.end())
- {
- LOG_WARN("Monster Manager: Ignoring duplicate definition of "
- "monster '" << id << "'!");
- continue;
- }
+ if (mMonsterClassesByName.contains(name))
+ LOG_WARN("Monster Manager: Name not unique for monster " << id);
+ else
+ mMonsterClassesByName.insert(name, monster);
+ }
- MonsterClass *monster = new MonsterClass(id);
- mMonsterClasses[id] = monster;
+ MonsterDrops drops;
+ bool attributesSet = false;
+ bool behaviorSet = false;
- if (!name.empty())
+ for_each_xml_child_node(subnode, node)
+ {
+ if (xmlStrEqual(subnode->name, BAD_CAST "drop"))
{
- monster->setName(name);
-
- if (mMonsterClassesByName.contains(name))
- LOG_WARN("Monster Manager: Name not unique for monster " << id);
+ MonsterDrop drop;
+ std::string item = XML::getProperty(subnode, "item",
+ std::string());
+ ItemClass *itemClass;
+ if (utils::isNumeric(item))
+ itemClass = itemManager->getItem(utils::stringToInt(item));
else
- mMonsterClassesByName.insert(name, monster);
- }
+ itemClass = itemManager->getItemByName(item);
- MonsterDrops drops;
- bool attributesSet = false;
- bool behaviorSet = false;
-
- for_each_xml_child_node(subnode, node)
- {
- if (xmlStrEqual(subnode->name, BAD_CAST "drop"))
+ if (!itemClass)
{
- MonsterDrop drop;
- std::string item = XML::getProperty(subnode, "item",
- std::string());
- ItemClass *itemClass;
- if (utils::isNumeric(item))
- itemClass = itemManager->getItem(utils::stringToInt(item));
- else
- itemClass = itemManager->getItemByName(item);
-
- if (!itemClass)
- {
- LOG_WARN("Monster Manager: Invalid item name \"" << item
- << "\"");
- break;
- }
+ LOG_WARN("Monster Manager: Invalid item name \"" << item
+ << "\"");
+ break;
+ }
- drop.item = itemClass;
- drop.probability = XML::getFloatProperty(subnode, "percent",
- 0.0) * 100 + 0.5;
+ drop.item = itemClass;
+ drop.probability = XML::getFloatProperty(subnode, "percent",
+ 0.0) * 100 + 0.5;
- if (drop.probability)
- drops.push_back(drop);
- }
- else if (xmlStrEqual(subnode->name, BAD_CAST "attributes"))
+ if (drop.probability)
+ drops.push_back(drop);
+ }
+ else if (xmlStrEqual(subnode->name, BAD_CAST "attributes"))
+ {
+ attributesSet = true;
+
+ const int hp = XML::getProperty(subnode, "hp", -1);
+ monster->setAttribute(ATTR_MAX_HP, hp);
+ monster->setAttribute(ATTR_HP, hp);
+
+ monster->setAttribute(ATTR_DODGE,
+ XML::getProperty(subnode, "evade", -1));
+ monster->setAttribute(ATTR_MAGIC_DODGE,
+ XML::getProperty(subnode, "magic-evade", -1));
+ monster->setAttribute(ATTR_ACCURACY,
+ XML::getProperty(subnode, "hit", -1));
+ monster->setAttribute(ATTR_DEFENSE,
+ XML::getProperty(subnode, "physical-defence", -1));
+ monster->setAttribute(ATTR_MAGIC_DEFENSE,
+ XML::getProperty(subnode, "magical-defence", -1));
+ monster->setSize(XML::getProperty(subnode, "size", -1));
+ float speed = (XML::getFloatProperty(subnode, "speed", -1.0f));
+ monster->setMutation(XML::getProperty(subnode, "mutation", 0));
+ std::string genderString = XML::getProperty(subnode, "gender",
+ std::string());
+ monster->setGender(getGender(genderString));
+
+ // Checking attributes for completeness and plausibility
+ if (monster->getMutation() > MAX_MUTATION)
{
- attributesSet = true;
-
- const int hp = XML::getProperty(subnode, "hp", -1);
- monster->setAttribute(ATTR_MAX_HP, hp);
- monster->setAttribute(ATTR_HP, hp);
-
- monster->setAttribute(ATTR_DODGE,
- XML::getProperty(subnode, "evade", -1));
- monster->setAttribute(ATTR_MAGIC_DODGE,
- XML::getProperty(subnode, "magic-evade", -1));
- monster->setAttribute(ATTR_ACCURACY,
- XML::getProperty(subnode, "hit", -1));
- monster->setAttribute(ATTR_DEFENSE,
- XML::getProperty(subnode, "physical-defence", -1));
- monster->setAttribute(ATTR_MAGIC_DEFENSE,
- XML::getProperty(subnode, "magical-defence", -1));
- monster->setSize(XML::getProperty(subnode, "size", -1));
- float speed = (XML::getFloatProperty(subnode, "speed", -1.0f));
- monster->setMutation(XML::getProperty(subnode, "mutation", 0));
- std::string genderString = XML::getProperty(subnode, "gender",
- std::string());
- monster->setGender(getGender(genderString));
-
- // Checking attributes for completeness and plausibility
- if (monster->getMutation() > MAX_MUTATION)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": Mutation of monster Id:" << id << " more than "
- << MAX_MUTATION << "%. Defaulted to 0.");
- monster->setMutation(0);
- }
-
- bool attributesComplete = true;
- const AttributeManager::AttributeScope &mobAttr =
- attributeManager->getAttributeScope(MonsterScope);
+ LOG_WARN(filename
+ << ": Mutation of monster Id:" << id << " more than "
+ << MAX_MUTATION << "%. Defaulted to 0.");
+ monster->setMutation(0);
+ }
- for (AttributeManager::AttributeScope::const_iterator it =
- mobAttr.begin(), it_end = mobAttr.end(); it != it_end; ++it)
- {
- if (!monster->mAttributes.count(it->first))
- {
- LOG_WARN(mMonsterReferenceFile << ": No attribute "
- << it->first << " for monster Id: "
- << id << ". Defaulted to 0.");
- attributesComplete = false;
- monster->setAttribute(it->first, 0);
- }
- }
+ bool attributesComplete = true;
+ const AttributeManager::AttributeScope &mobAttr =
+ attributeManager->getAttributeScope(MonsterScope);
- if (monster->getSize() == -1)
+ for (AttributeManager::AttributeScope::const_iterator it =
+ mobAttr.begin(), it_end = mobAttr.end(); it != it_end; ++it)
+ {
+ if (!monster->mAttributes.count(it->first))
{
- LOG_WARN(mMonsterReferenceFile
- << ": No size set for monster Id:" << id << ". "
- << "Defaulted to " << DEFAULT_MONSTER_SIZE
- << " pixels.");
- monster->setSize(DEFAULT_MONSTER_SIZE);
+ LOG_WARN(filename << ": No attribute "
+ << it->first << " for monster Id: "
+ << id << ". Defaulted to 0.");
attributesComplete = false;
+ monster->setAttribute(it->first, 0);
}
+ }
- if (speed == -1.0f)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": No speed set for monster Id:" << id << ". "
- << "Defaulted to " << DEFAULT_MONSTER_SPEED
- << " tiles/second.");
- speed = DEFAULT_MONSTER_SPEED;
- attributesComplete = false;
- }
- monster->setAttribute(ATTR_MOVE_SPEED_TPS, speed);
+ if (monster->getSize() == -1)
+ {
+ LOG_WARN(filename
+ << ": No size set for monster Id:" << id << ". "
+ << "Defaulted to " << DEFAULT_MONSTER_SIZE
+ << " pixels.");
+ monster->setSize(DEFAULT_MONSTER_SIZE);
+ attributesComplete = false;
+ }
- if (!attributesComplete)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": Attributes incomplete for monster Id:" << id
- << ". Defaults values may have been applied!");
- }
+ if (speed == -1.0f)
+ {
+ LOG_WARN(filename
+ << ": No speed set for monster Id:" << id << ". "
+ << "Defaulted to " << DEFAULT_MONSTER_SPEED
+ << " tiles/second.");
+ speed = DEFAULT_MONSTER_SPEED;
+ attributesComplete = false;
+ }
+ monster->setAttribute(ATTR_MOVE_SPEED_TPS, speed);
+ if (!attributesComplete)
+ {
+ LOG_WARN(filename
+ << ": Attributes incomplete for monster Id:" << id
+ << ". Defaults values may have been applied!");
}
- else if (xmlStrEqual(subnode->name, BAD_CAST "exp"))
+
+ }
+ else if (xmlStrEqual(subnode->name, BAD_CAST "exp"))
+ {
+ xmlChar *exp = subnode->xmlChildrenNode->content;
+ monster->setExp(atoi((const char*)exp));
+ monster->setOptimalLevel(XML::getProperty(subnode, "level", 0));
+ }
+ else if (xmlStrEqual(subnode->name, BAD_CAST "behavior"))
+ {
+ behaviorSet = true;
+ if (XML::getBoolProperty(subnode, "aggressive", false))
+ monster->setAggressive(true);
+
+ monster->setTrackRange(
+ XML::getProperty(subnode, "track-range", 1));
+ monster->setStrollRange(
+ XML::getProperty(subnode, "stroll-range", 0));
+ monster->setAttackDistance(
+ XML::getProperty(subnode, "attack-distance", 0));
+ }
+ else if (xmlStrEqual(subnode->name, BAD_CAST "attack"))
+ {
+ AttackInfo *att = AttackInfo::readAttackNode(subnode);
+ bool validMonsterAttack = true;
+
+ if (att->getDamage().id < 1)
{
- xmlChar *exp = subnode->xmlChildrenNode->content;
- monster->setExp(atoi((const char*)exp));
- monster->setOptimalLevel(XML::getProperty(subnode, "level", 0));
+ LOG_WARN(filename
+ << ": Attack without ID for monster Id:"
+ << id << " (" << name << ") - attack ignored");
+ validMonsterAttack = false;
}
- else if (xmlStrEqual(subnode->name, BAD_CAST "behavior"))
+ else if (att->getDamage().element == ELEMENT_ILLEGAL)
{
- behaviorSet = true;
- if (XML::getBoolProperty(subnode, "aggressive", false))
- monster->setAggressive(true);
-
- monster->setTrackRange(
- XML::getProperty(subnode, "track-range", 1));
- monster->setStrollRange(
- XML::getProperty(subnode, "stroll-range", 0));
- monster->setAttackDistance(
- XML::getProperty(subnode, "attack-distance", 0));
+ LOG_WARN(filename
+ << ": Attack with unknown element for monster Id:"
+ << id << " (" << name << ") - attack ignored");
+ validMonsterAttack = false;
}
- else if (xmlStrEqual(subnode->name, BAD_CAST "attack"))
+ else if (att->getDamage().type == DAMAGE_OTHER)
{
- AttackInfo *att = AttackInfo::readAttackNode(subnode);
- bool validMonsterAttack = true;
-
- if (att->getDamage().id < 1)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": Attack without ID for monster Id:"
- << id << " (" << name << ") - attack ignored");
- validMonsterAttack = false;
- }
- else if (att->getDamage().element == ELEMENT_ILLEGAL)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": Attack with unknown element for monster Id:"
- << id << " (" << name << ") - attack ignored");
- validMonsterAttack = false;
- }
- else if (att->getDamage().type == DAMAGE_OTHER)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": Attack with unknown damage type "
- << "for monster Id:" << id
- << " (" << name << ")");
- validMonsterAttack = false;
- }
-
- if (validMonsterAttack)
- {
- monster->addAttack(att);
- }
- else
- {
- delete att;
- att = 0;
- }
+ LOG_WARN(filename
+ << ": Attack with unknown damage type "
+ << "for monster Id:" << id
+ << " (" << name << ")");
+ validMonsterAttack = false;
+ }
+ if (validMonsterAttack)
+ {
+ monster->addAttack(att);
}
- else if (xmlStrEqual(subnode->name, BAD_CAST "vulnerability"))
+ else
{
- Element element = elementFromString(
- XML::getProperty(subnode, "element", std::string()));
- double factor = XML::getFloatProperty(subnode, "factor", 1.0);
- monster->setVulnerability(element, factor);
+ delete att;
+ att = 0;
}
- }
- monster->setDrops(drops);
- if (!attributesSet)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": No attributes defined for monster Id:" << id
- << " (" << name << ")");
- }
- if (!behaviorSet)
- {
- LOG_WARN(mMonsterReferenceFile
- << ": No behavior defined for monster Id:" << id
- << " (" << name << ")");
}
- if (monster->getExp() == -1)
+ else if (xmlStrEqual(subnode->name, BAD_CAST "vulnerability"))
{
- LOG_WARN(mMonsterReferenceFile
- << ": No experience defined for monster Id:" << id
- << " (" << name << ")");
- monster->setExp(0);
+ Element element = elementFromString(
+ XML::getProperty(subnode, "element", std::string()));
+ double factor = XML::getFloatProperty(subnode, "factor", 1.0);
+ monster->setVulnerability(element, factor);
}
- ++nbMonsters;
}
- LOG_INFO("Loaded " << nbMonsters << " monsters from "
- << mMonsterReferenceFile << '.');
-}
-
-void MonsterManager::deinitialize()
-{
- for (MonsterClasses::iterator i = mMonsterClasses.begin(),
- i_end = mMonsterClasses.end(); i != i_end; ++i)
+ monster->setDrops(drops);
+ if (!attributesSet)
{
- delete i->second;
+ LOG_WARN(filename
+ << ": No attributes defined for monster Id:" << id
+ << " (" << name << ")");
+ }
+ if (!behaviorSet)
+ {
+ LOG_WARN(filename
+ << ": No behavior defined for monster Id:" << id
+ << " (" << name << ")");
+ }
+ if (monster->getExp() == -1)
+ {
+ LOG_WARN(filename
+ << ": No experience defined for monster Id:" << id
+ << " (" << name << ")");
+ monster->setExp(0);
}
- mMonsterClasses.clear();
- mMonsterClassesByName.clear();
-}
-
-MonsterClass *MonsterManager::getMonsterByName(const std::string &name) const
-{
- return mMonsterClassesByName.value(name);
}
-MonsterClass *MonsterManager::getMonster(int id) const
+/**
+ * Check the status of recently loaded configuration.
+ */
+void MonsterManager::checkStatus()
{
- MonsterClasses::const_iterator i = mMonsterClasses.find(id);
- return i != mMonsterClasses.end() ? i->second : 0;
+ LOG_INFO("Loaded " << mMonsterClasses.size() << " monsters");
}