update houses/monsters/items xml readers
This commit is contained in:
parent
b0e6b3b8fb
commit
5015ced156
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue