update houses/monsters/items xml readers
This commit is contained in:
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);
|
||||||
uint16 id = stdext::unsafe_cast<uint16>(element->Attribute("id"));
|
newType->setServerId(id);
|
||||||
if(!(otbType = getOtbType(id))) {
|
addOtbType(newType);
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) {
|
if(id != 0)
|
||||||
if(attr->ValueTStr() != "attribute")
|
parseItemType(id, element);
|
||||||
continue;
|
else {
|
||||||
|
uint16 fromId = element->readType<uint16>("fromid"), toId = element->readType<uint16>("toid");
|
||||||
otbType->unserializeXML(attr);
|
for(uint16 i = fromId; i < toId; ++i)
|
||||||
|
parseItemType(i, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.Clear();
|
doc.Clear();
|
||||||
m_xmlLoaded = true;
|
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)
|
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…
Reference in New Issue