update houses/monsters/items xml readers

master
niczkx 12 years ago
parent b0e6b3b8fb
commit 5015ced156

@ -22,6 +22,8 @@
#include "map.h" #include "map.h"
#include <framework/core/resourcemanager.h>
House::House(uint32 hId, const std::string &name, const Position &pos) House::House(uint32 hId, const std::string &name, const Position &pos)
: m_id(hId), m_name(name) : m_id(hId), m_name(name)
{ {
@ -83,9 +85,10 @@ HousePtr Houses::getHouse(uint32 houseId)
void Houses::load(const std::string& fileName) void Houses::load(const std::string& fileName)
{ {
TiXmlDocument doc(fileName.c_str()); TiXmlDocument doc;
if(!doc.LoadFile()) doc.Parse(g_resources.loadFile(fileName).c_str());
stdext::throw_exception(stdext::format("failed to load '%s' (House XML)", fileName)); if(doc.Error())
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
TiXmlElement *root = doc.FirstChildElement(); TiXmlElement *root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "houses") if(!root || root->ValueTStr() != "houses")

@ -376,33 +376,40 @@ void Map::loadSpawns(const std::string &fileName)
if(!m_monsters.isLoaded()) if(!m_monsters.isLoaded())
stdext::throw_exception("cannot load spawns; monsters aren't loaded."); stdext::throw_exception("cannot load spawns; monsters aren't loaded.");
TiXmlDocument doc(fileName); TiXmlDocument doc;
if(!doc.LoadFile()) doc.Parse(g_resources.loadFile(fileName).c_str());
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s", fileName)); if(doc.Error())
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "spawns") if(!root || root->ValueStr() != "spawns")
stdext::throw_exception("malformed spawns file"); stdext::throw_exception("malformed spawns file");
for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) { for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
if (node->ValueTStr() != "spawn") if(node->ValueTStr() != "spawn")
stdext::throw_exception("invalid spawn node"); stdext::throw_exception("invalid spawn node");
Position centerPos = node->readPos("center"); Position centerPos = node->readPos("center");
for(TiXmlElement* mType = node->FirstChildElement(); mType; mType = mType->NextSiblingElement()) { for(TiXmlElement* mType = node->FirstChildElement(); mType; mType = mType->NextSiblingElement()) {
if (mType->ValueStr() != "monster") if(mType->ValueStr() != "monster" && mType->ValueStr() != "npc")
stdext::throw_exception("invalid spawn-subnode"); stdext::throw_exception(stdext::format("invalid spawn-subnode %s", mType->ValueStr()));
if(mType->ValueStr() == "npc") // escape npc's for now...
continue;
std::string mName = mType->Attribute("name"); std::string mName = mType->Attribute("name");
MonsterTypePtr m = m_monsters.getMonster(mName); MonsterTypePtr m = getMonster(mName);
if (!m) if (!m)
stdext::throw_exception(stdext::format("unkown monster %s", mName)); stdext::throw_exception(stdext::format("unkown monster '%s'", stdext::trim(stdext::tolower(mName))));
Point off = mType->readPoint(); Point off = mType->readPoint();
Position mPos(centerPos.x + off.x, centerPos.y + off.y, centerPos.z); Position mPos(centerPos.x + off.x, centerPos.y + off.y, centerPos.z);
m->setPos(mPos); m->setPos(mPos);
m->setSpawnTime(mType->readType<int>("spawntime"));
} }
} }
doc.Clear();
g_logger.debug("Loaded spawns");
} }
bool Map::loadOtcm(const std::string& fileName) bool Map::loadOtcm(const std::string& fileName)
@ -1026,5 +1033,5 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
MonsterTypePtr Map::getMonster(const std::string& name) MonsterTypePtr Map::getMonster(const std::string& name)
{ {
return m_monsters.getMonster(stdext::trim(stdext::tolower(name))); return m_monsters.getMonster(name);
} }

@ -24,20 +24,27 @@
#include "creature.h" #include "creature.h"
#include <framework/xml/tinyxml.h> #include <framework/xml/tinyxml.h>
#include <framework/core/resourcemanager.h>
void Monsters::loadMonsters(const std::string& file) void Monsters::loadMonsters(const std::string& file)
{ {
TiXmlDocument doc(file); TiXmlDocument doc;
if(!doc.LoadFile()) doc.Parse(g_resources.loadFile(file).c_str());
stdext::throw_exception(stdext::format("cannot open monsters file '%s'", file)); if(doc.Error())
stdext::throw_exception(stdext::format("cannot open monsters file '%s': '%s'", file, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "monsters") if(!root || root->ValueStr() != "monsters")
stdext::throw_exception("malformed monsters xml file"); stdext::throw_exception("malformed monsters xml file");
for(TiXmlElement* monster = root->FirstChildElement(); root; root = root->NextSiblingElement()) { for(TiXmlElement* monster = root->FirstChildElement(); monster; monster = monster->NextSiblingElement()) {
MonsterTypePtr newMonster(new MonsterType(monster->Attribute("name"))); MonsterTypePtr newMonster(new MonsterType(stdext::trim(stdext::tolower(monster->Attribute("name")))));
loadSingleMonster(file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file"), newMonster); std::string fname = file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file");
if(fname.substr(fname.length() - 4) != ".xml")
fname += ".xml";
loadSingleMonster(fname, newMonster);
} }
doc.Clear(); doc.Clear();
@ -49,9 +56,10 @@ void Monsters::loadSingleMonster(const std::string& file, const MonsterTypePtr&
if (!m || std::find(m_monsters.begin(), m_monsters.end(), m) != m_monsters.end()) if (!m || std::find(m_monsters.begin(), m_monsters.end(), m) != m_monsters.end())
stdext::throw_exception("reloading monsters is not supported yet."); stdext::throw_exception("reloading monsters is not supported yet.");
TiXmlDocument doc(file); TiXmlDocument doc;
if(!doc.LoadFile()) doc.Parse(g_resources.loadFile(file).c_str());
stdext::throw_exception(stdext::format("cannot load single monster file '%s'", file)); if(doc.Error())
stdext::throw_exception(stdext::format("cannot load single monster file '%s': '%s'", file, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "monster") if(!root || root->ValueStr() != "monster")
@ -61,21 +69,20 @@ void Monsters::loadSingleMonster(const std::string& file, const MonsterTypePtr&
if(attrib->ValueStr() == "look") { if(attrib->ValueStr() == "look") {
Outfit out; Outfit out;
int type = attrib->readType<int>("type"); int type = 0;
if (type <= 0) if(!attrib->Attribute("type").empty())
type = attrib->readType<int>("type");
else
type = attrib->readType<int>("typeex"); type = attrib->readType<int>("typeex");
if(type) { out.setId(type);
out.setId(type); {
{ out.setHead(attrib->readType<int>(("head")));
out.setHead(attrib->readType<int>(("head"))); out.setBody(attrib->readType<int>(("body")));
out.setBody(attrib->readType<int>(("body"))); out.setLegs(attrib->readType<int>(("legs")));
out.setLegs(attrib->readType<int>(("legs"))); out.setFeet(attrib->readType<int>(("feet")));
out.setFeet(attrib->readType<int>(("feet"))); out.setAddons(attrib->readType<int>(("addons")));
out.setAddons(attrib->readType<int>(("addons"))); out.setMount(attrib->readType<int>(("mount")));
out.setMount(attrib->readType<int>(("mount"))); }
}
} else
stdext::throw_exception(stdext::format("invalid look type/typeex for monster %s", m->getName()));
m->setOutfit(out); m->setOutfit(out);
} }
} }
@ -86,7 +93,7 @@ void Monsters::loadSingleMonster(const std::string& file, const MonsterTypePtr&
MonsterTypePtr Monsters::getMonster(const std::string& name) MonsterTypePtr Monsters::getMonster(const std::string& name)
{ {
auto it = std::find_if(m_monsters.begin(), m_monsters.end(), auto it = std::find_if(m_monsters.begin(), m_monsters.end(),
[=] (const MonsterTypePtr& m) -> bool { return m->getName() == name; }); [=] (const MonsterTypePtr& m) -> bool { return m->getName() == stdext::trim(stdext::tolower(name)); });
return it != m_monsters.end() ? *it : nullptr; return it != m_monsters.end() ? *it : nullptr;
} }

@ -37,6 +37,7 @@ public:
void setPos(const Position& pos) { m_pos = pos; } void setPos(const Position& pos) { m_pos = pos; }
void setName(const std::string& name) { m_name = name; } void setName(const std::string& name) { m_name = name; }
void setOutfit(const Outfit& o) { m_outfit = o; } void setOutfit(const Outfit& o) { m_outfit = o; }
void setSpawnTime(int spawnTime) { m_spawnTime = spawnTime; }
std::string getName() { return m_name; } std::string getName() { return m_name; }
Position getPos() { return m_pos; } Position getPos() { return m_pos; }
@ -46,6 +47,7 @@ private:
Position m_pos; Position m_pos;
std::string m_name; std::string m_name;
Outfit m_outfit; Outfit m_outfit;
int m_spawnTime;
}; };
class Monsters class Monsters

@ -124,56 +124,63 @@ void ThingTypeManager::loadOtb(const std::string& file)
void ThingTypeManager::loadXml(const std::string& file) void ThingTypeManager::loadXml(const std::string& file)
{ {
TiXmlDocument doc(file.c_str()); TiXmlDocument doc;
if(!doc.LoadFile()) doc.Parse(g_resources.loadFile(file).c_str());
stdext::throw_exception(stdext::format("failed to load xml '%s'", file)); if(doc.Error())
stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "items") if(!root || root->ValueTStr() != "items")
stdext::throw_exception("invalid root tag name"); stdext::throw_exception("invalid root tag name");
ThingTypeOtbPtr otbType = nullptr;
for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
if(element->ValueTStr() != "item") if(element->ValueTStr() != "item")
continue; continue;
std::string name = element->Attribute("id"); uint16 id = element->readType<uint16>("id");
if(name.empty()) if(id > 20000 && id < 20100) {
continue; id -= 20000;
ThingTypeOtbPtr newType(new ThingTypeOtb);
newType->setServerId(id);
addOtbType(newType);
}
uint16 id = stdext::unsafe_cast<uint16>(element->Attribute("id")); if(id != 0)
if(!(otbType = getOtbType(id))) { parseItemType(id, element);
// try reading fromId toId else {
uint16 from = stdext::unsafe_cast<uint16>(element->Attribute("fromId")); uint16 fromId = element->readType<uint16>("fromid"), toId = element->readType<uint16>("toid");
uint16 to = stdext::unsafe_cast<uint16>(element->Attribute("toid")); for(uint16 i = fromId; i < toId; ++i)
parseItemType(i, element);
}
}
for (uint16 __id = from; __id < to; ++__id) { doc.Clear();
if(!(otbType = getOtbType(__id))) m_xmlLoaded = true;
continue; g_logger.debug("items.xml read successfully.");
}
otbType->setHasRange(); void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
otbType->setFromServerId(from); {
otbType->setToServerId(to); uint16 serverId = id;
break; if(serverId > 20000 && id < 20100) {
} serverId -= 20000;
// perform last check ThingTypeOtbPtr newType(new ThingTypeOtb);
if(!otbType) { newType->setServerId(serverId);
stdext::throw_exception(stdext::format("failed to find item with server id %d - tried reading fromid to id", addOtbType(newType);
id)); }
}
}
for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) { ThingTypeOtbPtr otbType = getOtbType(serverId);
if(attr->ValueTStr() != "attribute") otbType->setName(elem->Attribute("name"));
continue; for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
if(attrib->ValueStr() != "attribute")
break;
otbType->unserializeXML(attr); if(attrib->Attribute("key") == "description") {
otbType->setDesc(attrib->Attribute("value"));
break;
} }
} }
doc.Clear();
m_xmlLoaded = true;
} }
void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType) void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType)

@ -38,6 +38,7 @@ public:
bool loadDat(const std::string& file); bool loadDat(const std::string& file);
void loadOtb(const std::string& file); void loadOtb(const std::string& file);
void loadXml(const std::string& file); void loadXml(const std::string& file);
void parseItemType(uint16 id, TiXmlElement *elem);
void addOtbType(const ThingTypeOtbPtr& otbType); void addOtbType(const ThingTypeOtbPtr& otbType);
const ThingTypeOtbPtr& findOtbForClientId(uint16 id); const ThingTypeOtbPtr& findOtbForClientId(uint16 id);

@ -21,6 +21,7 @@
*/ */
#include "thingtypemanager.h"
#include "thingtypeotb.h" #include "thingtypeotb.h"
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
@ -41,6 +42,7 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
node->getU32(); // flags node->getU32(); // flags
static uint16 lastId = 99;
while(node->canRead()) { while(node->canRead()) {
uint8 attr = node->getU8(); uint8 attr = node->getU8();
if(attr == 0 || attr == 0xFF) if(attr == 0 || attr == 0xFF)
@ -48,10 +50,20 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
uint16 len = node->getU16(); uint16 len = node->getU16();
switch(attr) { switch(attr) {
case OtbAttribServerId: case OtbAttribServerId: {
m_serverId = node->getU16(); m_serverId = node->getU16();
if(m_serverId > 20000 && m_serverId < 20100) {
m_serverId -= 20000;
} else if(lastId > 99 && lastId != m_serverId - 1) {
static ThingTypeOtbPtr dummyType(g_things.getNullOtbType());
while(lastId != m_serverId - 1) {
dummyType->setServerId(++lastId);
g_things.addOtbType(dummyType);
}
}
assert(len == 2); assert(len == 2);
break; break;
}
case OtbAttribClientId: case OtbAttribClientId:
m_clientId = node->getU16(); m_clientId = node->getU16();
assert(len == 2); assert(len == 2);
@ -62,14 +74,3 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
} }
} }
} }
void ThingTypeOtb::unserializeXML(const TiXmlElement* elem)
{
std::string key = elem->Attribute("key");
std::string value = elem->Attribute("value");
if(key == "name")
setName(value);
else if(key == "description")
setDesc(value);
}

@ -87,31 +87,24 @@ public:
ThingTypeOtb(); ThingTypeOtb();
void unserialize(const BinaryTreePtr& node); void unserialize(const BinaryTreePtr& node);
void unserializeXML(const TiXmlElement* elem);
uint16 getServerId() { return m_serverId; } uint16 getServerId() { return m_serverId; }
uint16 getClientId() { return m_clientId; } uint16 getClientId() { return m_clientId; }
OtbCategory getCategory() { return m_category; } OtbCategory getCategory() { return m_category; }
bool isNull() { return m_null; } bool isNull() { return m_null; }
bool hasRange() { return m_hasRange; }
void setHasRange() { m_hasRange = true; } void setServerId(uint16 serverId) { m_serverId = serverId; }
void setFromServerId(uint16 from) { m_fromId = from; }
void setToServerId(uint16 to) { m_toId = to; }
void setName(const std::string& name) { m_name = name; } void setName(const std::string& name) { m_name = name; }
void setDesc(const std::string& desc) { m_desc = desc; } void setDesc(const std::string& desc) { m_desc = desc; }
private: private:
uint16 m_serverId; uint16 m_serverId;
uint16 m_clientId; uint16 m_clientId;
uint16 m_fromId, m_toId;
std::string m_name, m_desc; std::string m_name, m_desc;
OtbCategory m_category; OtbCategory m_category;
Boolean<true> m_null; Boolean<true> m_null;
Boolean<false> m_hasRange;
}; };
#endif #endif

Loading…
Cancel
Save