More work on OTBM/OTB/XML
This commit is contained in:
parent
8cd8829048
commit
1ed95b6120
|
@ -181,32 +181,3 @@ Point BinaryTree::getPoint()
|
||||||
ret.y = getU8();
|
ret.y = getU8();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BinaryWriteTree
|
|
||||||
BinaryWriteTree::BinaryWriteTree(const FileStreamPtr& fin) :
|
|
||||||
m_fin(fin)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BinaryWriteTree::~BinaryWriteTree()
|
|
||||||
{
|
|
||||||
m_fin->close();
|
|
||||||
m_fin = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriteTree::startNode(uint8 type)
|
|
||||||
{
|
|
||||||
writeU8(BINARYTREE_NODE_START);
|
|
||||||
writeU8(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriteTree::endNode()
|
|
||||||
{
|
|
||||||
writeU8(BINARYTREE_NODE_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriteTree::writeU8(uint8 u8) { m_fin->addU8(u8); }
|
|
||||||
void BinaryWriteTree::writeU16(uint16 u16) { m_fin->addU16(u16); }
|
|
||||||
void BinaryWriteTree::writeU32(uint32 u32) { m_fin->addU32(u32); }
|
|
||||||
void BinaryWriteTree::writeString(const std::string& str) { m_fin->addString(str); }
|
|
||||||
|
|
||||||
|
|
|
@ -66,25 +66,4 @@ private:
|
||||||
uint m_startPos;
|
uint m_startPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BinaryWriteTree : public stdext::shared_object
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BinaryWriteTree(const FileStreamPtr& fin);
|
|
||||||
~BinaryWriteTree();
|
|
||||||
|
|
||||||
void startNode(uint8 type);
|
|
||||||
void endNode();
|
|
||||||
|
|
||||||
void writeU8(uint8 u8);
|
|
||||||
void writeU16(uint16 u16);
|
|
||||||
void writeU32(uint32 u32);
|
|
||||||
void writeString(const std::string& str);
|
|
||||||
|
|
||||||
void writePoint(const Point& p) { writeU8(p.x); writeU8(p.y); }
|
|
||||||
void writePos(const Position& p) { writeU16(p.x); writeU16(p.y); writeU8(p.z); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
FileStreamPtr m_fin;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -267,6 +267,17 @@ BinaryTreePtr FileStream::getBinaryTree()
|
||||||
return BinaryTreePtr(new BinaryTree(asFileStream()));
|
return BinaryTreePtr(new BinaryTree(asFileStream()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileStream::startNode(uint8 n)
|
||||||
|
{
|
||||||
|
addU8(BINARYTREE_NODE_START);
|
||||||
|
addU8(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileStream::endNode()
|
||||||
|
{
|
||||||
|
addU8(BINARYTREE_NODE_END);
|
||||||
|
}
|
||||||
|
|
||||||
void FileStream::addU8(uint8 v)
|
void FileStream::addU8(uint8 v)
|
||||||
{
|
{
|
||||||
if(!m_caching) {
|
if(!m_caching) {
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "declarations.h"
|
#include "declarations.h"
|
||||||
#include <framework/luaengine/luaobject.h>
|
#include <framework/luaengine/luaobject.h>
|
||||||
#include <framework/util/databuffer.h>
|
#include <framework/util/databuffer.h>
|
||||||
|
#include <otclient/position.h>
|
||||||
|
#include <framework/util/point.h>
|
||||||
|
|
||||||
struct PHYSFS_File;
|
struct PHYSFS_File;
|
||||||
|
|
||||||
|
@ -55,11 +57,15 @@ public:
|
||||||
std::string getString();
|
std::string getString();
|
||||||
BinaryTreePtr getBinaryTree();
|
BinaryTreePtr getBinaryTree();
|
||||||
|
|
||||||
|
void startNode(uint8 n);
|
||||||
|
void endNode();
|
||||||
void addU8(uint8 v);
|
void addU8(uint8 v);
|
||||||
void addU16(uint16 v);
|
void addU16(uint16 v);
|
||||||
void addU32(uint32 v);
|
void addU32(uint32 v);
|
||||||
void addU64(uint64 v);
|
void addU64(uint64 v);
|
||||||
void addString(const std::string& v);
|
void addString(const std::string& v);
|
||||||
|
void addPos(const Position& pos) { addU16(pos.x); addU16(pos.y); addU8(pos.z); }
|
||||||
|
void addPoint(const Point& p) { addU8(p.x); addU8(p.y); }
|
||||||
|
|
||||||
FileStreamPtr asFileStream() { return static_self_cast<FileStream>(); }
|
FileStreamPtr asFileStream() { return static_self_cast<FileStream>(); }
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
Creatures g_creatures;
|
||||||
|
|
||||||
void Creatures::loadMonsters(const std::string& file)
|
void Creatures::loadMonsters(const std::string& file)
|
||||||
{
|
{
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
|
@ -127,7 +129,7 @@ bool Creatures::m_loadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr
|
||||||
return type >= 0;
|
return type >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureTypePtr Creatures::getCreature(std::string name)
|
CreatureTypePtr Creatures::getCreatureByName(std::string name)
|
||||||
{
|
{
|
||||||
stdext::tolower(name);
|
stdext::tolower(name);
|
||||||
stdext::trim(name);
|
stdext::trim(name);
|
||||||
|
@ -135,3 +137,14 @@ CreatureTypePtr Creatures::getCreature(std::string name)
|
||||||
[=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; });
|
[=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; });
|
||||||
return it != m_creatures.end() ? *it : nullptr;
|
return it != m_creatures.end() ? *it : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreatureTypePtr Creatures::getCreatureByLook(int look)
|
||||||
|
{
|
||||||
|
auto findFun = [=] (const CreatureTypePtr& c) -> bool
|
||||||
|
{
|
||||||
|
const Outfit& o = c->getOutfit();
|
||||||
|
return o.getId() == look;
|
||||||
|
};
|
||||||
|
auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
|
||||||
|
return it != m_creatures.end() ? *it : nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -41,14 +41,15 @@ public:
|
||||||
CreatureType() { }
|
CreatureType() { }
|
||||||
CreatureType(const std::string& name) { setName(name); }
|
CreatureType(const std::string& name) { setName(name); }
|
||||||
|
|
||||||
void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
|
|
||||||
void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
|
|
||||||
void setSpawnTime(int spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
|
void setSpawnTime(int spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
|
||||||
|
|
||||||
std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); }
|
|
||||||
Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); }
|
|
||||||
int getSpawnTime() { return m_attribs.get<int>(CreatureAttrSpawnTime); }
|
int getSpawnTime() { return m_attribs.get<int>(CreatureAttrSpawnTime); }
|
||||||
|
|
||||||
|
void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
|
||||||
|
std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); }
|
||||||
|
|
||||||
|
void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
|
||||||
|
Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
stdext::dynamic_storage<uint8> m_attribs;
|
stdext::dynamic_storage<uint8> m_attribs;
|
||||||
};
|
};
|
||||||
|
@ -63,7 +64,9 @@ public:
|
||||||
void loadNpcs(const std::string& folder);
|
void loadNpcs(const std::string& folder);
|
||||||
void loadCreatureBuffer(const std::string& buffer);
|
void loadCreatureBuffer(const std::string& buffer);
|
||||||
|
|
||||||
CreatureTypePtr getCreature(std::string name);
|
CreatureTypePtr getCreatureByName(std::string name);
|
||||||
|
CreatureTypePtr getCreatureByLook(int look);
|
||||||
|
|
||||||
bool isLoaded() const { return m_loaded; }
|
bool isLoaded() const { return m_loaded; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -74,4 +77,6 @@ private:
|
||||||
stdext::boolean<false> m_loaded;
|
stdext::boolean<false> m_loaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Creatures g_creatures;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,7 +42,7 @@ void Effect::onAppear()
|
||||||
|
|
||||||
// hack to fix some animation phases duration, currently there is no better solution
|
// hack to fix some animation phases duration, currently there is no better solution
|
||||||
if(m_id == 33)
|
if(m_id == 33)
|
||||||
m_phaseDuration *= 4;
|
m_phaseDuration <<= 2;
|
||||||
|
|
||||||
// schedule removal
|
// schedule removal
|
||||||
auto self = asEffect();
|
auto self = asEffect();
|
||||||
|
|
|
@ -268,41 +268,45 @@ void Item::unserializeItem(const BinaryTreePtr &in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::serializeItem(const BinaryWriteTreePtr& out)
|
void Item::serializeItem(const FileStreamPtr& out)
|
||||||
{
|
{
|
||||||
out->startNode(OTBM_ITEM);
|
out->startNode(OTBM_ITEM);
|
||||||
out->writeU16(getId());
|
out->addU16(getId());
|
||||||
|
|
||||||
out->writeU8(ATTR_COUNT);
|
out->addU8(ATTR_COUNT);
|
||||||
out->writeU8(getCount());
|
out->addU8(getCount());
|
||||||
|
|
||||||
out->writeU8(ATTR_CHARGES);
|
out->addU8(ATTR_CHARGES);
|
||||||
out->writeU16(getCountOrSubType());
|
out->addU16(getCountOrSubType());
|
||||||
|
|
||||||
Position dest = m_attribs.get<Position>(ATTR_TELE_DEST);
|
Position dest = m_attribs.get<Position>(ATTR_TELE_DEST);
|
||||||
if(dest.isValid()) {
|
if(dest.isValid()) {
|
||||||
out->writeU8(ATTR_TELE_DEST);
|
out->addU8(ATTR_TELE_DEST);
|
||||||
out->writePos(dest);
|
out->addPos(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isDepot()) {
|
if(isDepot()) {
|
||||||
out->writeU8(ATTR_DEPOT_ID);
|
out->addU8(ATTR_DEPOT_ID);
|
||||||
out->writeU16(getDepotId());
|
out->addU16(getDepotId());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID);
|
uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID);
|
||||||
uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID);
|
uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID);
|
||||||
if(aid) {
|
if(aid) {
|
||||||
out->writeU8(ATTR_ACTION_ID);
|
out->addU8(ATTR_ACTION_ID);
|
||||||
out->writeU16(aid);
|
out->addU16(aid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uid) {
|
if(uid) {
|
||||||
out->writeU8(ATTR_UNIQUE_ID);
|
out->addU8(ATTR_UNIQUE_ID);
|
||||||
out->writeU16(uid);
|
out->addU16(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
out->endNode();
|
out->endNode();
|
||||||
|
if(!m_containerItems.empty()) {
|
||||||
|
for(auto c : m_containerItems)
|
||||||
|
c->serializeItem(out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Item::getSubType()
|
int Item::getSubType()
|
||||||
|
|
|
@ -98,7 +98,7 @@ public:
|
||||||
ItemPtr clone();
|
ItemPtr clone();
|
||||||
|
|
||||||
void unserializeItem(const BinaryTreePtr& in);
|
void unserializeItem(const BinaryTreePtr& in);
|
||||||
void serializeItem(const BinaryWriteTreePtr& out);
|
void serializeItem(const FileStreamPtr& out);
|
||||||
|
|
||||||
void setDepotId(uint16 depotId) { m_attribs.set(ATTR_DEPOT_ID, depotId); }
|
void setDepotId(uint16 depotId) { m_attribs.set(ATTR_DEPOT_ID, depotId); }
|
||||||
uint16 getDepotId() { return m_attribs.get<uint16>(ATTR_DEPOT_ID); }
|
uint16 getDepotId() { return m_attribs.get<uint16>(ATTR_DEPOT_ID); }
|
||||||
|
@ -119,6 +119,8 @@ public:
|
||||||
ItemPtr asItem() { return static_self_cast<Item>(); }
|
ItemPtr asItem() { return static_self_cast<Item>(); }
|
||||||
bool isItem() { return true; }
|
bool isItem() { return true; }
|
||||||
|
|
||||||
|
void addContainerItem(const ItemPtr& i) { m_containerItems.push_back(i); }
|
||||||
|
|
||||||
const ThingTypePtr& getThingType();
|
const ThingTypePtr& getThingType();
|
||||||
ThingType *rawGetThingType();
|
ThingType *rawGetThingType();
|
||||||
|
|
||||||
|
@ -127,6 +129,7 @@ private:
|
||||||
uint16 m_otbId;
|
uint16 m_otbId;
|
||||||
uint8 m_countOrSubType;
|
uint8 m_countOrSubType;
|
||||||
stdext::packed_storage<uint8> m_attribs;
|
stdext::packed_storage<uint8> m_attribs;
|
||||||
|
std::vector<ItemPtr> m_containerItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -41,6 +41,7 @@ void ItemType::unserialize(const BinaryTreePtr& node)
|
||||||
node->getU32(); // flags
|
node->getU32(); // flags
|
||||||
|
|
||||||
static uint16 lastId = 99;
|
static uint16 lastId = 99;
|
||||||
|
static ItemTypePtr nullType = g_things.getNullItemType();
|
||||||
while(node->canRead()) {
|
while(node->canRead()) {
|
||||||
uint8 attr = node->getU8();
|
uint8 attr = node->getU8();
|
||||||
if(attr == 0 || attr == 0xFF)
|
if(attr == 0 || attr == 0xFF)
|
||||||
|
@ -53,10 +54,13 @@ void ItemType::unserialize(const BinaryTreePtr& node)
|
||||||
if(serverId > 20000 && serverId < 20100) {
|
if(serverId > 20000 && serverId < 20100) {
|
||||||
serverId -= 20000;
|
serverId -= 20000;
|
||||||
} else if(lastId > 99 && lastId != serverId - 1) {
|
} else if(lastId > 99 && lastId != serverId - 1) {
|
||||||
while(lastId != serverId - 1)
|
while(lastId != serverId - 1) {
|
||||||
++lastId;
|
nullType->setServerId(lastId++);
|
||||||
|
g_things.addItemType(nullType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setServerId(serverId);
|
setServerId(serverId);
|
||||||
|
lastId = serverId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemTypeAttrClientId: {
|
case ItemTypeAttrClientId: {
|
||||||
|
@ -67,10 +71,6 @@ void ItemType::unserialize(const BinaryTreePtr& node)
|
||||||
setName(node->getString(len));
|
setName(node->getString(len));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemTypeAttrDesc: {
|
|
||||||
setDesc(node->getString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
node->skip(len); // skip attribute
|
node->skip(len); // skip attribute
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <framework/luaengine/luaobject.h>
|
#include <framework/luaengine/luaobject.h>
|
||||||
#include <framework/xml/tinyxml.h>
|
#include <framework/xml/tinyxml.h>
|
||||||
|
|
||||||
enum ItemCategory {
|
enum ItemCategory : uint8 {
|
||||||
ItemCategoryInvalid = 0,
|
ItemCategoryInvalid = 0,
|
||||||
ItemCategoryGround = 1,
|
ItemCategoryGround = 1,
|
||||||
ItemCategoryContainer = 2,
|
ItemCategoryContainer = 2,
|
||||||
|
@ -86,19 +86,23 @@ public:
|
||||||
|
|
||||||
void unserialize(const BinaryTreePtr& node);
|
void unserialize(const BinaryTreePtr& node);
|
||||||
|
|
||||||
|
void setServerId(uint16 serverId) { m_attribs.set(ItemTypeAttrServerId, serverId); }
|
||||||
uint16 getServerId() { return m_attribs.get<uint16>(ItemTypeAttrServerId); }
|
uint16 getServerId() { return m_attribs.get<uint16>(ItemTypeAttrServerId); }
|
||||||
|
|
||||||
|
void setClientId(uint16 clientId) { m_attribs.set(ItemTypeAttrClientId, clientId); }
|
||||||
uint16 getClientId() { return m_attribs.get<uint16>(ItemTypeAttrClientId); }
|
uint16 getClientId() { return m_attribs.get<uint16>(ItemTypeAttrClientId); }
|
||||||
|
|
||||||
|
void setCategory(ItemCategory category) { m_category = category; }
|
||||||
ItemCategory getCategory() { return m_category; }
|
ItemCategory getCategory() { return m_category; }
|
||||||
|
|
||||||
|
void setName(const std::string& name) { m_attribs.set(ItemTypeAttrName, name); }
|
||||||
std::string getName() { return m_attribs.get<std::string>(ItemTypeAttrName); }
|
std::string getName() { return m_attribs.get<std::string>(ItemTypeAttrName); }
|
||||||
|
|
||||||
|
void setDesc(const std::string& desc) { m_attribs.set(ItemTypeAttrDesc, desc); }
|
||||||
std::string getDesc() { return m_attribs.get<std::string>(ItemTypeAttrDesc); }
|
std::string getDesc() { return m_attribs.get<std::string>(ItemTypeAttrDesc); }
|
||||||
|
|
||||||
bool isNull() { return m_null; }
|
bool isNull() { return m_null; }
|
||||||
|
|
||||||
void setClientId(uint16 clientId) { m_attribs.set(ItemTypeAttrClientId, clientId); }
|
|
||||||
void setServerId(uint16 serverId) { m_attribs.set(ItemTypeAttrServerId, serverId); }
|
|
||||||
void setName(const std::string& name) { m_attribs.set(ItemTypeAttrName, name); }
|
|
||||||
void setDesc(const std::string& desc) { m_attribs.set(ItemTypeAttrDesc, desc); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ItemCategory m_category;
|
ItemCategory m_category;
|
||||||
stdext::boolean<true> m_null;
|
stdext::boolean<true> m_null;
|
||||||
|
|
|
@ -59,9 +59,11 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "getThingType", &ThingTypeManager::getThingType, &g_things);
|
g_lua.bindSingletonFunction("g_things", "getThingType", &ThingTypeManager::getThingType, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things);
|
g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things);
|
||||||
|
g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things);
|
g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
|
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
|
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
|
||||||
|
g_lua.bindSingletonFunction("g_things", "castThingToCreature", &ThingTypeManager::castThingToCreature, &g_things);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
g_lua.registerSingletonClass("g_houses");
|
g_lua.registerSingletonClass("g_houses");
|
||||||
|
@ -112,6 +114,11 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindSingletonFunction("g_map", "getHouse", &Map::getHouse, &g_map);
|
g_lua.bindSingletonFunction("g_map", "getHouse", &Map::getHouse, &g_map);
|
||||||
g_lua.bindSingletonFunction("g_map", "getCreature", &Map::getCreature, &g_map);
|
g_lua.bindSingletonFunction("g_map", "getCreature", &Map::getCreature, &g_map);
|
||||||
|
|
||||||
|
/// \todo move creatures from Map to here
|
||||||
|
g_lua.registerSingletonClass("g_creatures");
|
||||||
|
g_lua.bindSingletonFunction("g_creatures", "getCreature", &Creatures::getCreatureByName, &g_creatures);
|
||||||
|
g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &Creatures::getCreatureByLook, &g_creatures);
|
||||||
|
|
||||||
g_lua.registerSingletonClass("g_game");
|
g_lua.registerSingletonClass("g_game");
|
||||||
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
|
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
|
||||||
g_lua.bindSingletonFunction("g_game", "cancelLogin", &Game::cancelLogin, &g_game);
|
g_lua.bindSingletonFunction("g_game", "cancelLogin", &Game::cancelLogin, &g_game);
|
||||||
|
@ -340,6 +347,7 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindClassMemberFunction<ThingType>("getId", &ThingType::getId);
|
g_lua.bindClassMemberFunction<ThingType>("getId", &ThingType::getId);
|
||||||
g_lua.bindClassMemberFunction<ThingType>("getMarketData", &ThingType::getMarketData);
|
g_lua.bindClassMemberFunction<ThingType>("getMarketData", &ThingType::getMarketData);
|
||||||
g_lua.bindClassMemberFunction<ThingType>("getClothSlot", &ThingType::getClothSlot);
|
g_lua.bindClassMemberFunction<ThingType>("getClothSlot", &ThingType::getClothSlot);
|
||||||
|
g_lua.bindClassMemberFunction<ThingType>("getCategory", &ThingType::getCategory);
|
||||||
|
|
||||||
g_lua.registerClass<Item, Thing>();
|
g_lua.registerClass<Item, Thing>();
|
||||||
g_lua.bindClassStaticFunction<Item>("create", &Item::create);
|
g_lua.bindClassStaticFunction<Item>("create", &Item::create);
|
||||||
|
|
|
@ -69,7 +69,7 @@ void Map::clean()
|
||||||
|
|
||||||
m_towns.clear();
|
m_towns.clear();
|
||||||
m_houses.clear();
|
m_houses.clear();
|
||||||
m_creatures.clear();
|
g_creatures.clear();
|
||||||
m_tilesRect = Rect(65534, 65534, 0, 0);
|
m_tilesRect = Rect(65534, 65534, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ public:
|
||||||
void saveOtbm(const std::string& fileName);
|
void saveOtbm(const std::string& fileName);
|
||||||
|
|
||||||
void loadSpawns(const std::string& fileName);
|
void loadSpawns(const std::string& fileName);
|
||||||
void saveSpawns(const std::string&) { }
|
void saveSpawns(const std::string&);
|
||||||
|
|
||||||
// otbm attributes (description, size, etc.)
|
// otbm attributes (description, size, etc.)
|
||||||
void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); }
|
void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); }
|
||||||
|
@ -201,9 +201,9 @@ public:
|
||||||
Size getSize() { return Size(m_attribs.get<uint16>(OTBM_ATTR_WIDTH), m_attribs.get<uint16>(OTBM_ATTR_HEIGHT)); }
|
Size getSize() { return Size(m_attribs.get<uint16>(OTBM_ATTR_WIDTH), m_attribs.get<uint16>(OTBM_ATTR_HEIGHT)); }
|
||||||
std::vector<std::string> getDescriptions() { return stdext::split(m_attribs.get<std::string>(OTBM_ATTR_DESCRIPTION), "\n"); }
|
std::vector<std::string> getDescriptions() { return stdext::split(m_attribs.get<std::string>(OTBM_ATTR_DESCRIPTION), "\n"); }
|
||||||
|
|
||||||
void loadMonsters(const std::string& fileName) { m_creatures.loadMonsters(fileName); }
|
void loadMonsters(const std::string& fileName) { g_creatures.loadMonsters(fileName); }
|
||||||
void loadSingleCreature(const std::string& file) { m_creatures.loadSingleCreature(file); }
|
void loadSingleCreature(const std::string& file) { g_creatures.loadSingleCreature(file); }
|
||||||
void loadNpcs(const std::string& folder) { m_creatures.loadNpcs(folder); }
|
void loadNpcs(const std::string& folder) { g_creatures.loadNpcs(folder); }
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
void cleanDynamicThings();
|
void cleanDynamicThings();
|
||||||
|
@ -234,7 +234,7 @@ public:
|
||||||
// town/house/monster related
|
// town/house/monster related
|
||||||
TownPtr getTown(uint32 tid) { return m_towns.getTown(tid); }
|
TownPtr getTown(uint32 tid) { return m_towns.getTown(tid); }
|
||||||
HousePtr getHouse(uint32 hid) { return m_houses.getHouse(hid); }
|
HousePtr getHouse(uint32 hid) { return m_houses.getHouse(hid); }
|
||||||
CreatureTypePtr getCreature(const std::string &name) { return m_creatures.getCreature(name); }
|
CreatureTypePtr getCreature(const std::string &name) { return g_creatures.getCreatureByName(name); }
|
||||||
|
|
||||||
void setLight(const Light& light) { m_light = light; }
|
void setLight(const Light& light) { m_light = light; }
|
||||||
void setCentralPosition(const Position& centralPosition);
|
void setCentralPosition(const Position& centralPosition);
|
||||||
|
@ -273,7 +273,6 @@ private:
|
||||||
stdext::packed_storage<uint8> m_attribs;
|
stdext::packed_storage<uint8> m_attribs;
|
||||||
Houses m_houses;
|
Houses m_houses;
|
||||||
Towns m_towns;
|
Towns m_towns;
|
||||||
Creatures m_creatures;
|
|
||||||
static TilePtr m_nulltile;
|
static TilePtr m_nulltile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ void Map::loadOtbm(const std::string& fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const BinaryTreePtr &nodeMapData : node->getChildren()) {
|
for(const BinaryTreePtr& nodeMapData : node->getChildren()) {
|
||||||
uint8 mapDataType = nodeMapData->getU8();
|
uint8 mapDataType = nodeMapData->getU8();
|
||||||
if(mapDataType == OTBM_TILE_AREA) {
|
if(mapDataType == OTBM_TILE_AREA) {
|
||||||
Position basePos = nodeMapData->getPosition();
|
Position basePos = nodeMapData->getPosition();
|
||||||
|
@ -149,7 +149,7 @@ void Map::loadOtbm(const std::string& fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const BinaryTreePtr &nodeItem : nodeTile->getChildren()) {
|
for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
|
||||||
if(nodeItem->getU8() != OTBM_ITEM)
|
if(nodeItem->getU8() != OTBM_ITEM)
|
||||||
stdext::throw_exception("invalid item node");
|
stdext::throw_exception("invalid item node");
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ void Map::loadOtbm(const std::string& fileName)
|
||||||
|
|
||||||
ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
|
ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
|
||||||
cItem->unserializeItem(containerItem);
|
cItem->unserializeItem(containerItem);
|
||||||
//item->addContainerItem(cItem);
|
item->addContainerItem(cItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,9 +175,12 @@ void Map::loadOtbm(const std::string& fileName)
|
||||||
addThing(item, pos);
|
addThing(item, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(const TilePtr& tile = getTile(pos))
|
if(const TilePtr& tile = getTile(pos)) {
|
||||||
|
if(house)
|
||||||
|
tile->setHouseId(house->getId());
|
||||||
tile->setFlags((tileflags_t)flags);
|
tile->setFlags((tileflags_t)flags);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if(mapDataType == OTBM_TOWNS) {
|
} else if(mapDataType == OTBM_TOWNS) {
|
||||||
TownPtr town = nullptr;
|
TownPtr town = nullptr;
|
||||||
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
|
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
|
||||||
|
@ -263,41 +266,40 @@ void Map::saveOtbm(const std::string &fileName)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fin->addU32(0); // file version
|
fin->addU32(0); // file version
|
||||||
BinaryWriteTreePtr root(new BinaryWriteTree(fin));
|
fin->startNode(0);
|
||||||
root->startNode(0);
|
|
||||||
{
|
{
|
||||||
root->writeU32(version);
|
fin->addU32(version);
|
||||||
|
|
||||||
Size mapSize = getSize();
|
Size mapSize = getSize();
|
||||||
root->writeU16(mapSize.width());
|
fin->addU16(mapSize.width());
|
||||||
root->writeU16(mapSize.height());
|
fin->addU16(mapSize.height());
|
||||||
|
|
||||||
root->writeU32(g_things.getOtbMajorVersion());
|
fin->addU32(g_things.getOtbMajorVersion());
|
||||||
root->writeU32(g_things.getOtbMinorVersion());
|
fin->addU32(g_things.getOtbMinorVersion());
|
||||||
|
|
||||||
root->startNode(OTBM_MAP_DATA);
|
fin->startNode(OTBM_MAP_DATA);
|
||||||
{
|
{
|
||||||
// own description.
|
// own description.
|
||||||
for(const auto& desc : getDescriptions()) {
|
for(const auto& desc : getDescriptions()) {
|
||||||
root->writeU8(OTBM_ATTR_DESCRIPTION);
|
fin->addU8(OTBM_ATTR_DESCRIPTION);
|
||||||
root->writeString(desc);
|
fin->addString(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// special one
|
// special one
|
||||||
root->writeU8(OTBM_ATTR_DESCRIPTION);
|
fin->addU8(OTBM_ATTR_DESCRIPTION);
|
||||||
root->writeString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));
|
fin->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));
|
||||||
|
|
||||||
// spawn file.
|
// spawn file.
|
||||||
root->writeU8(OTBM_ATTR_SPAWN_FILE);
|
fin->addU8(OTBM_ATTR_SPAWN_FILE);
|
||||||
root->writeString(spawnFile);
|
fin->addString(spawnFile);
|
||||||
|
|
||||||
// house file.
|
// house file.
|
||||||
if(version > 1) {
|
if(version > 1) {
|
||||||
root->writeU8(OTBM_ATTR_HOUSE_FILE);
|
fin->addU8(OTBM_ATTR_HOUSE_FILE);
|
||||||
root->writeString(houseFile);
|
fin->addString(houseFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
Position base(-1, -1, -1);
|
Position base(0, 0, 0);
|
||||||
bool firstNode = true;
|
bool firstNode = true;
|
||||||
|
|
||||||
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
|
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
|
||||||
|
@ -311,71 +313,72 @@ void Map::saveOtbm(const std::string &fileName)
|
||||||
if(!pos.isValid())
|
if(!pos.isValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(pos.x < base.x || pos.x >= base.x + 256 || pos.y < base.y|| pos.y >= base.y + 256 ||
|
if(pos.x < base.x || pos.x >= base.x + 255
|
||||||
pos.z != base.z) {
|
|| pos.y < base.y || pos.y >= base.y + 255
|
||||||
|
|| pos.z != base.z) {
|
||||||
if(!firstNode)
|
if(!firstNode)
|
||||||
root->endNode(); /// OTBM_TILE_AREA
|
fin->endNode(); /// OTBM_TILE_AREA
|
||||||
|
|
||||||
root->startNode(OTBM_TILE_AREA);
|
fin->startNode(OTBM_TILE_AREA);
|
||||||
firstNode = false;
|
firstNode = false;
|
||||||
root->writePos(base = pos & 0xFF00);
|
fin->addPos(base = pos & 0xFF00);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 flags = tile->getFlags();
|
uint32 flags = tile->getFlags();
|
||||||
|
|
||||||
root->startNode((flags & TILESTATE_HOUSE) == TILESTATE_HOUSE ? OTBM_HOUSETILE : OTBM_TILE);
|
fin->startNode((flags & TILESTATE_HOUSE) == TILESTATE_HOUSE ? OTBM_HOUSETILE : OTBM_TILE);
|
||||||
root->writePoint(Point(pos.x, pos.y) & 0xFF);
|
fin->addPoint(Point(pos.x, pos.y) & 0xFF);
|
||||||
// if(tileNode->getType() == OTBM_HOUSETILE)
|
if((flags & TILESTATE_HOUSE) == TILESTATE_HOUSE)
|
||||||
// tileNode->writeU32(tile->getHouseId());
|
fin->addU32(tile->getHouseId());
|
||||||
|
|
||||||
if(flags) {
|
if(flags) {
|
||||||
root->writeU8(OTBM_ATTR_TILE_FLAGS);
|
fin->addU8(OTBM_ATTR_TILE_FLAGS);
|
||||||
root->writeU32(flags);
|
fin->addU32(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const ItemPtr& item : tile->getItems()) {
|
for(const ItemPtr& item : tile->getItems()) {
|
||||||
if(item->isGround()) {
|
if(item->isGround()) {
|
||||||
root->writeU8(OTBM_ATTR_ITEM);
|
fin->addU8(OTBM_ATTR_ITEM);
|
||||||
root->writeU16(item->getId());
|
fin->addU16(item->getId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->serializeItem(root);
|
item->serializeItem(fin);
|
||||||
}
|
}
|
||||||
|
|
||||||
root->endNode(); // OTBM_TILE
|
fin->endNode(); // OTBM_TILE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!firstNode)
|
if(!firstNode)
|
||||||
root->endNode(); // OTBM_TILE_AREA
|
fin->endNode(); // OTBM_TILE_AREA
|
||||||
|
|
||||||
root->startNode(OTBM_TOWNS);
|
fin->startNode(OTBM_TOWNS);
|
||||||
for(const TownPtr& town : m_towns.getTowns()) {
|
for(const TownPtr& town : m_towns.getTowns()) {
|
||||||
root->writeU32(town->getId());
|
fin->addU32(town->getId());
|
||||||
root->writeString(town->getName());
|
fin->addString(town->getName());
|
||||||
root->writePos(town->getPos());
|
fin->addPos(town->getPos());
|
||||||
}
|
}
|
||||||
root->endNode();
|
fin->endNode();
|
||||||
|
|
||||||
if(version > 1) {
|
if(version > 1) {
|
||||||
root->startNode(OTBM_WAYPOINTS);
|
fin->startNode(OTBM_WAYPOINTS);
|
||||||
for(const auto& it : m_waypoints) {
|
for(const auto& it : m_waypoints) {
|
||||||
root->writeString(it.second);
|
fin->addString(it.second);
|
||||||
root->writePos(it.first);
|
fin->addPos(it.first);
|
||||||
}
|
}
|
||||||
root->endNode();
|
fin->endNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root->endNode(); // OTBM_MAP_DATA
|
fin->endNode(); // OTBM_MAP_DATA
|
||||||
}
|
}
|
||||||
root->endNode(); // 0 (root)
|
fin->endNode(); // 0 (root)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::loadSpawns(const std::string &fileName)
|
void Map::loadSpawns(const std::string &fileName)
|
||||||
{
|
{
|
||||||
if(!m_creatures.isLoaded())
|
if(!g_creatures.isLoaded())
|
||||||
stdext::throw_exception("cannot load spawns; monsters/nps aren't loaded.");
|
stdext::throw_exception("cannot load spawns; monsters/nps aren't loaded.");
|
||||||
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
|
@ -401,7 +404,7 @@ void Map::loadSpawns(const std::string &fileName)
|
||||||
stdext::tolower(cName);
|
stdext::tolower(cName);
|
||||||
stdext::trim(cName);
|
stdext::trim(cName);
|
||||||
|
|
||||||
if (!(cType = m_creatures.getCreature(cName)))
|
if (!(cType = g_creatures.getCreatureByName(cName)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cType->setSpawnTime(cNode->readType<int>("spawntime"));
|
cType->setSpawnTime(cNode->readType<int>("spawntime"));
|
||||||
|
@ -420,6 +423,21 @@ void Map::loadSpawns(const std::string &fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Map::saveSpawns(const std::string& fileName)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
TiXmlDocument doc;
|
||||||
|
|
||||||
|
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
|
||||||
|
doc.LinkEndChild(decl);
|
||||||
|
|
||||||
|
TiXmlElement* root = new TiXmlElement("spawns");
|
||||||
|
doc.LinkEndChild(root);
|
||||||
|
|
||||||
|
TiXmlElement* spawn = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool Map::loadOtcm(const std::string& fileName)
|
bool Map::loadOtcm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include "thingtype.h"
|
#include "thingtype.h"
|
||||||
#include "itemtype.h"
|
#include "itemtype.h"
|
||||||
|
#include "creature.h"
|
||||||
|
#include "creatures.h"
|
||||||
|
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
|
@ -125,7 +127,9 @@ void ThingTypeManager::loadOtb(const std::string& file)
|
||||||
|
|
||||||
void ThingTypeManager::loadXml(const std::string& file)
|
void ThingTypeManager::loadXml(const std::string& file)
|
||||||
{
|
{
|
||||||
/// Read XML
|
if(!isOtbLoaded())
|
||||||
|
stdext::throw_exception("OTB must be loaded before XML");
|
||||||
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
doc.Parse(g_resources.loadFile(file).c_str());
|
doc.Parse(g_resources.loadFile(file).c_str());
|
||||||
if(doc.Error())
|
if(doc.Error())
|
||||||
|
@ -140,19 +144,27 @@ void ThingTypeManager::loadXml(const std::string& file)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint16 id = element->readType<uint16>("id");
|
uint16 id = element->readType<uint16>("id");
|
||||||
if(id > 20000 && id < 20100) {
|
if(id != 0) {
|
||||||
id -= 20000;
|
std::vector<std::string> s_ids = stdext::split(element->Attribute("id"), ";");
|
||||||
ItemTypePtr newType(new ItemType);
|
for(const std::string& s : s_ids) {
|
||||||
newType->setServerId(id);
|
std::vector<int32> ids = stdext::split<int32>(s, "-");
|
||||||
addItemType(newType);
|
if(ids.size() > 1) {
|
||||||
|
int32 i = ids[0];
|
||||||
|
while(i <= ids[1])
|
||||||
|
parseItemType(i++, element);
|
||||||
|
} else
|
||||||
|
parseItemType(atoi(s.c_str()), element);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::vector<int32> begin = stdext::split<int32>(element->Attribute("fromid"), ";");
|
||||||
|
std::vector<int32> end = stdext::split<int32>(element->Attribute("toid"), ";");
|
||||||
|
if(begin[0] && begin.size() == end.size()) {
|
||||||
|
size_t size = begin.size();
|
||||||
|
for(size_t i = 0; i < size; ++i) {
|
||||||
|
while(begin[i] <= end[i])
|
||||||
|
parseItemType(begin[i]++, element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,23 +176,53 @@ void ThingTypeManager::loadXml(const std::string& file)
|
||||||
void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
|
void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
|
||||||
{
|
{
|
||||||
uint16 serverId = id;
|
uint16 serverId = id;
|
||||||
|
ItemTypePtr itemType = nullptr;
|
||||||
if(serverId > 20000 && id < 20100) {
|
if(serverId > 20000 && id < 20100) {
|
||||||
serverId -= 20000;
|
serverId -= 20000;
|
||||||
|
|
||||||
ItemTypePtr newType(new ItemType);
|
itemType = ItemTypePtr(new ItemType);
|
||||||
newType->setServerId(serverId);
|
itemType->setServerId(serverId);
|
||||||
addItemType(newType);
|
addItemType(itemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!itemType) {
|
||||||
|
itemType = getItemType(serverId);
|
||||||
|
if(itemType == m_nullItemType) {
|
||||||
|
itemType = ItemTypePtr(new ItemType);
|
||||||
|
itemType->setServerId(id);
|
||||||
|
addItemType(itemType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTypePtr itemType = getItemType(serverId);
|
|
||||||
itemType->setName(elem->Attribute("name"));
|
itemType->setName(elem->Attribute("name"));
|
||||||
for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
|
for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
|
||||||
if(attrib->ValueStr() != "attribute")
|
std::string key = attrib->Attribute("key");
|
||||||
break;
|
if(key.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
if(attrib->Attribute("key") == "description") {
|
stdext::tolower(key);
|
||||||
|
if(key == "description")
|
||||||
itemType->setDesc(attrib->Attribute("value"));
|
itemType->setDesc(attrib->Attribute("value"));
|
||||||
break;
|
else if(key == "weapontype")
|
||||||
|
itemType->setCategory(ItemCategoryWeapon);
|
||||||
|
else if(key == "ammotype")
|
||||||
|
itemType->setCategory(ItemCategoryAmmunition);
|
||||||
|
else if(key == "armor")
|
||||||
|
itemType->setCategory(ItemCategoryArmor);
|
||||||
|
else if(key == "charges")
|
||||||
|
itemType->setCategory(ItemCategoryCharges);
|
||||||
|
else if(key == "type") {
|
||||||
|
std::string value = attrib->Attribute("value");
|
||||||
|
stdext::tolower(value);
|
||||||
|
|
||||||
|
if(value == "key")
|
||||||
|
itemType->setCategory(ItemCategoryKey);
|
||||||
|
else if(value == "magicfield")
|
||||||
|
itemType->setCategory(ItemCategoryMagicField);
|
||||||
|
else if(value == "teleport")
|
||||||
|
itemType->setCategory(ItemCategoryTeleport);
|
||||||
|
else if(value == "door")
|
||||||
|
itemType->setCategory(ItemCategoryDoor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +231,7 @@ void ThingTypeManager::addItemType(const ItemTypePtr& itemType)
|
||||||
{
|
{
|
||||||
uint16 id = itemType->getServerId();
|
uint16 id = itemType->getServerId();
|
||||||
if(m_itemTypes.size() <= id)
|
if(m_itemTypes.size() <= id)
|
||||||
m_itemTypes.resize(id+1, m_nullItemType);
|
m_itemTypes.resize((id * 3) / 2 + 1, m_nullItemType);
|
||||||
m_itemTypes[id] = itemType;
|
m_itemTypes[id] = itemType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,13 +259,36 @@ const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory cate
|
||||||
|
|
||||||
const ItemTypePtr& ThingTypeManager::getItemType(uint16 id)
|
const ItemTypePtr& ThingTypeManager::getItemType(uint16 id)
|
||||||
{
|
{
|
||||||
if(id >= m_itemTypes.size()) {
|
if(id >= m_itemTypes.size() || m_itemTypes[id] == m_nullItemType) {
|
||||||
g_logger.error(stdext::format("invalid thing type server id %d", id));
|
g_logger.error(stdext::format("invalid thing type server id %d", id));
|
||||||
return m_nullItemType;
|
return m_nullItemType;
|
||||||
}
|
}
|
||||||
return m_itemTypes[id];
|
return m_itemTypes[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreaturePtr ThingTypeManager::castThingToCreature(const ThingTypePtr& thing)
|
||||||
|
{
|
||||||
|
if(!thing)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if(thing->getCategory() != ThingCategoryCreature)
|
||||||
|
stdext::throw_exception("Thing type is not a creature");
|
||||||
|
|
||||||
|
uint16 clientId = thing->getId();
|
||||||
|
CreaturePtr ret(new Creature);
|
||||||
|
CreatureTypePtr cType = g_creatures.getCreatureByLook(clientId);
|
||||||
|
if(!cType) {
|
||||||
|
// a creature can have a look item with whether client id or even server id
|
||||||
|
const ItemTypePtr& item = findItemTypeByClientId(clientId);
|
||||||
|
if(item && !(cType = g_creatures.getCreatureByLook(item->getServerId())))
|
||||||
|
stdext::throw_exception(stdext::format("failed to find creature with look type/item %hd", clientId));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->setName(cType->getName());
|
||||||
|
ret->setOutfit(cType->getOutfit());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ThingTypeList ThingTypeManager::findThingTypeByAttr(ThingAttr attr, ThingCategory category)
|
ThingTypeList ThingTypeManager::findThingTypeByAttr(ThingAttr attr, ThingCategory category)
|
||||||
{
|
{
|
||||||
ThingTypeList ret;
|
ThingTypeList ret;
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
const ItemTypePtr& getItemType(uint16 id);
|
const ItemTypePtr& getItemType(uint16 id);
|
||||||
ThingType* rawGetThingType(uint16 id, ThingCategory category) { return m_thingTypes[category][id].get(); }
|
ThingType* rawGetThingType(uint16 id, ThingCategory category) { return m_thingTypes[category][id].get(); }
|
||||||
ItemType* rawGetItemType(uint16 id) { return m_itemTypes[id].get(); }
|
ItemType* rawGetItemType(uint16 id) { return m_itemTypes[id].get(); }
|
||||||
|
CreaturePtr castThingToCreature(const ThingTypePtr& thing);
|
||||||
|
|
||||||
ThingTypeList findThingTypeByAttr(ThingAttr attr, ThingCategory category);
|
ThingTypeList findThingTypeByAttr(ThingAttr attr, ThingCategory category);
|
||||||
ItemTypeList findItemTypeByCategory(ItemCategory category);
|
ItemTypeList findItemTypeByCategory(ItemCategory category);
|
||||||
|
|
|
@ -109,7 +109,7 @@ public:
|
||||||
void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; }
|
void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; }
|
||||||
uint32 getFlags() { return m_flags; }
|
uint32 getFlags() { return m_flags; }
|
||||||
|
|
||||||
void setHouseId(uint32 hid) { if(m_flags & TILESTATE_HOUSE) m_houseId = hid; }
|
void setHouseId(uint32 hid) { m_houseId = hid; }
|
||||||
uint32 getHouseId() { return m_houseId; }
|
uint32 getHouseId() { return m_houseId; }
|
||||||
|
|
||||||
TilePtr asTile() { return static_self_cast<Tile>(); }
|
TilePtr asTile() { return static_self_cast<Tile>(); }
|
||||||
|
|
Loading…
Reference in New Issue