update houses/monsters/items xml readers

This commit is contained in:
niczkx 2012-07-18 13:46:58 +02:00
parent b0e6b3b8fb
commit 5015ced156
8 changed files with 111 additions and 90 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,6 +21,7 @@
*/
#include "thingtypemanager.h"
#include "thingtypeotb.h"
#include <framework/core/filestream.h>
@ -41,6 +42,7 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
node->getU32(); // flags
static uint16 lastId = 99;
while(node->canRead()) {
uint8 attr = node->getU8();
if(attr == 0 || attr == 0xFF)
@ -48,10 +50,20 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
uint16 len = node->getU16();
switch(attr) {
case OtbAttribServerId:
case OtbAttribServerId: {
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);
break;
}
case OtbAttribClientId:
m_clientId = node->getU16();
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);
}

View File

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