More refactoring and some changes

* Move protocol safeSend() to send()
* Bind some new functions
* Refactor lots of enums
master
Eduardo Bart 12 years ago
parent a6d53532d2
commit a11d6e501e

@ -59,8 +59,7 @@ void ModuleManager::autoLoadModules(int maxPriority)
if(priority > maxPriority) if(priority > maxPriority)
break; break;
ModulePtr module = pair.second; ModulePtr module = pair.second;
if(!module->isLoaded() && !module->load()) module->load();
g_logger.fatal("A required module has failed to load, cannot continue to run.");
} }
} }

@ -628,7 +628,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<Protocol>("disconnect", &Protocol::disconnect); g_lua.bindClassMemberFunction<Protocol>("disconnect", &Protocol::disconnect);
g_lua.bindClassMemberFunction<Protocol>("isConnected", &Protocol::isConnected); g_lua.bindClassMemberFunction<Protocol>("isConnected", &Protocol::isConnected);
g_lua.bindClassMemberFunction<Protocol>("isConnecting", &Protocol::isConnecting); g_lua.bindClassMemberFunction<Protocol>("isConnecting", &Protocol::isConnecting);
g_lua.bindClassMemberFunction<Protocol>("send", &Protocol::send); // must change to safeSend g_lua.bindClassMemberFunction<Protocol>("send", &Protocol::send);
g_lua.bindClassMemberFunction<Protocol>("recv", &Protocol::recv); g_lua.bindClassMemberFunction<Protocol>("recv", &Protocol::recv);
g_lua.bindClassMemberFunction<Protocol>("getXteaKey", &Protocol::getXteaKey); g_lua.bindClassMemberFunction<Protocol>("getXteaKey", &Protocol::getXteaKey);
g_lua.bindClassMemberFunction<Protocol>("generateXteaKey", &Protocol::generateXteaKey); g_lua.bindClassMemberFunction<Protocol>("generateXteaKey", &Protocol::generateXteaKey);

@ -30,7 +30,6 @@
#include <iomanip> #include <iomanip>
#include <vector> #include <vector>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <otclient/position.h>
#include "types.h" #include "types.h"
#include "cast.h" #include "cast.h"
@ -53,7 +52,7 @@ typename std::enable_if<std::is_integral<T>::value ||
std::is_floating_point<T>::value || std::is_floating_point<T>::value ||
std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; } std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; }
/// Cast any class or struct convertible to std::string /// Cast std::string
inline const char *sprintf_cast(const std::string& s) { return s.c_str(); } inline const char *sprintf_cast(const std::string& s) { return s.c_str(); }
template<int N> template<int N>
@ -181,11 +180,6 @@ inline std::string ip_to_string(uint32 ip) {
return std::string(host); return std::string(host);
} }
inline std::string pos_to_string(const Position& p)
{
return format("{x = %hd, y = %hd, z = %hd}", p.x, p.y, p.z);
}
/// Convert utf8 characters to latin1 /// Convert utf8 characters to latin1
inline char utf8CharToLatin1(uchar *utf8, int *read) { inline char utf8CharToLatin1(uchar *utf8, int *read) {
char c = '?'; char c = '?';

@ -89,7 +89,7 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction) void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction)
{ {
// outfit is a real creature // outfit is a real creature
if(m_outfit.getCategory() == DatCreatureCategory) { if(m_outfit.getCategory() == ThingCategoryCreature) {
int animationPhase = animateWalk ? m_walkAnimationPhase : 0; int animationPhase = animateWalk ? m_walkAnimationPhase : 0;
if(isAnimateAlways() && animateIdle) { if(isAnimateAlways() && animateIdle) {
@ -121,13 +121,13 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
g_painter->setCompositionMode(Painter::CompositionMode_Multiply); g_painter->setCompositionMode(Painter::CompositionMode_Multiply);
g_painter->setColor(m_outfit.getHeadColor()); g_painter->setColor(m_outfit.getHeadColor());
datType->draw(dest, scaleFactor, DatYellowMask, xPattern, yPattern, 0, animationPhase); datType->draw(dest, scaleFactor, SpriteMaskYellow, xPattern, yPattern, 0, animationPhase);
g_painter->setColor(m_outfit.getBodyColor()); g_painter->setColor(m_outfit.getBodyColor());
datType->draw(dest, scaleFactor, DatRedMask, xPattern, yPattern, 0, animationPhase); datType->draw(dest, scaleFactor, SpriteMaskRed, xPattern, yPattern, 0, animationPhase);
g_painter->setColor(m_outfit.getLegsColor()); g_painter->setColor(m_outfit.getLegsColor());
datType->draw(dest, scaleFactor, DatGreenMask, xPattern, yPattern, 0, animationPhase); datType->draw(dest, scaleFactor, SpriteMaskGreen, xPattern, yPattern, 0, animationPhase);
g_painter->setColor(m_outfit.getFeetColor()); g_painter->setColor(m_outfit.getFeetColor());
datType->draw(dest, scaleFactor, DatBlueMask, xPattern, yPattern, 0, animationPhase); datType->draw(dest, scaleFactor, SpriteMaskBlue, xPattern, yPattern, 0, animationPhase);
g_painter->setColor(oldColor); g_painter->setColor(oldColor);
g_painter->setCompositionMode(oldComposition); g_painter->setCompositionMode(oldComposition);
} }
@ -140,7 +140,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
// when creature is an effect we cant render the first and last animation phase, // when creature is an effect we cant render the first and last animation phase,
// instead we should loop in the phases between // instead we should loop in the phases between
if(m_outfit.getCategory() == DatEffectCategory) { if(m_outfit.getCategory() == ThingCategoryEffect) {
animationPhases = std::max(1, animationPhases-2); animationPhases = std::max(1, animationPhases-2);
animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME; animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME;
} }
@ -152,7 +152,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
animationPhase = animationPhases-1; animationPhase = animationPhases-1;
} }
if(m_outfit.getCategory() == DatEffectCategory) if(m_outfit.getCategory() == ThingCategoryEffect)
animationPhase = std::min(animationPhase+1, getAnimationPhases()); animationPhase = std::min(animationPhase+1, getAnimationPhases());
rawGetThingType()->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); rawGetThingType()->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase);
@ -305,7 +305,7 @@ void Creature::stopWalk()
void Creature::updateWalkAnimation(int totalPixelsWalked) void Creature::updateWalkAnimation(int totalPixelsWalked)
{ {
// update outfit animation // update outfit animation
if(m_outfit.getCategory() != DatCreatureCategory) if(m_outfit.getCategory() != ThingCategoryCreature)
return; return;
int footAnimPhases = getAnimationPhases() - 1; int footAnimPhases = getAnimationPhases() - 1;
@ -461,7 +461,7 @@ void Creature::setDirection(Otc::Direction direction)
void Creature::setOutfit(const Outfit& outfit) void Creature::setOutfit(const Outfit& outfit)
{ {
if(!g_things.isValidDatId(outfit.getId(), DatCreatureCategory)) if(!g_things.isValidDatId(outfit.getId(), ThingCategoryCreature))
return; return;
m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed. m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed.
m_outfit = outfit; m_outfit = outfit;

@ -28,12 +28,12 @@
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>
#include "outfit.h" #include "outfit.h"
enum CreatureAttributes : unsigned char enum CreatureAttr : uint8
{ {
CreatureAttribPos, CreatureAttrPosition = 0,
CreatureAttribName, CreatureAttrName = 1,
CreatureAttribOutfit, CreatureAttrOutfit = 2,
CreatureAttribSpawnTime CreatureAttrSpawnTime = 3
}; };
class CreatureType : public LuaObject class CreatureType : public LuaObject
@ -42,15 +42,15 @@ public:
CreatureType() { } CreatureType() { }
CreatureType(const std::string& name) { setName(name); } CreatureType(const std::string& name) { setName(name); }
void setPos(const Position& pos) { m_attribs.set(CreatureAttribPos, pos); } void setPos(const Position& pos) { m_attribs.set(CreatureAttrPosition, pos); }
void setName(const std::string& name) { m_attribs.set(CreatureAttribName, name); } void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttribOutfit, o); } void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
void setSpawnTime(int spawnTime) { m_attribs.set(CreatureAttribSpawnTime, spawnTime); } void setSpawnTime(int spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
std::string getName() { return m_attribs.get<std::string>(CreatureAttribName); } std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); }
Position getPos() { return m_attribs.get<Position>(CreatureAttribPos); } Position getPos() { return m_attribs.get<Position>(CreatureAttrPosition); }
Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttribOutfit); } Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); }
int getSpawnTime() { return m_attribs.get<int>(CreatureAttribSpawnTime); } int getSpawnTime() { return m_attribs.get<int>(CreatureAttrSpawnTime); }
private: private:
AttribStorage m_attribs; AttribStorage m_attribs;

@ -46,17 +46,17 @@ void Effect::startAnimation()
void Effect::setId(uint32 id) void Effect::setId(uint32 id)
{ {
if(!g_things.isValidDatId(id, DatEffectCategory)) if(!g_things.isValidDatId(id, ThingCategoryEffect))
id = 0; id = 0;
m_id = id; m_id = id;
} }
const ThingTypePtr& Effect::getThingType() const ThingTypePtr& Effect::getThingType()
{ {
return g_things.getThingType(m_id, DatEffectCategory); return g_things.getThingType(m_id, ThingCategoryEffect);
} }
ThingType *Effect::rawGetThingType() ThingType *Effect::rawGetThingType()
{ {
return g_things.rawGetThingType(m_id, DatEffectCategory); return g_things.rawGetThingType(m_id, ThingCategoryEffect);
} }

@ -640,7 +640,7 @@ void Game::use(const ThingPtr& thing)
void Game::useInventoryItem(int itemId) void Game::useInventoryItem(int itemId)
{ {
if(!canPerformGameAction() || !g_things.isValidDatId(itemId, DatItemCategory)) if(!canPerformGameAction() || !g_things.isValidDatId(itemId, ThingCategoryItem))
return; return;
Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory

@ -29,14 +29,14 @@
#include <framework/luaengine/luaobject.h> #include <framework/luaengine/luaobject.h>
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>
enum HouseAttributes : unsigned char enum HouseAttr : uint8
{ {
HouseAttribId, HouseAttrId,
HouseAttribName, HouseAttrName,
HouseAttribTown, HouseAttrTown,
HouseAttribEntry, HouseAttrEntry,
HouseAttribSize, HouseAttrSize,
HouseAttribRent HouseAttrRent
}; };
class House : public LuaObject class House : public LuaObject
@ -47,17 +47,17 @@ public:
~House() { m_tiles.clear(); } ~House() { m_tiles.clear(); }
void setTile(const TilePtr& tile); void setTile(const TilePtr& tile);
void setId(uint32 hId) { m_attribs.set(HouseAttribId, hId); } void setId(uint32 hId) { m_attribs.set(HouseAttrId, hId); }
void setName(const std::string& name) { m_attribs.set(HouseAttribName, name); } void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
void setTownId(uint32 tid) { m_attribs.set(HouseAttribTown, tid); } void setTownId(uint32 tid) { m_attribs.set(HouseAttrTown, tid); }
void setSize(uint32 s) { m_attribs.set(HouseAttribSize, s); } void setSize(uint32 s) { m_attribs.set(HouseAttrSize, s); }
void setRent(uint32 r) { m_attribs.set(HouseAttribRent, r); } void setRent(uint32 r) { m_attribs.set(HouseAttrRent, r); }
void setEntry(const Position& p) { m_attribs.set(HouseAttribEntry, p); } void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
uint32 getId() { return m_attribs.get<uint32>(HouseAttribId); } uint32 getId() { return m_attribs.get<uint32>(HouseAttrId); }
std::string getName() { return m_attribs.get<std::string>(HouseAttribName); } std::string getName() { return m_attribs.get<std::string>(HouseAttrName); }
uint32 getRent() { return m_attribs.get<uint32>(HouseAttribRent); } uint32 getRent() { return m_attribs.get<uint32>(HouseAttrRent); }
uint32 getSize() { return m_attribs.get<uint32>(HouseAttribSize); } uint32 getSize() { return m_attribs.get<uint32>(HouseAttrSize); }
protected: protected:
void load(const TiXmlElement* elem); void load(const TiXmlElement* elem);

@ -176,7 +176,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
void Item::setId(uint32 id) void Item::setId(uint32 id)
{ {
if(!g_things.isValidDatId(id, DatItemCategory)) if(!g_things.isValidDatId(id, ThingCategoryItem))
id = 0; id = 0;
//m_otbId = g_things.findOtbForClientId(id)->getServerId(); //m_otbId = g_things.findOtbForClientId(id)->getServerId();
m_id = id; m_id = id;
@ -194,7 +194,7 @@ void Item::setOtbId(uint16 id)
bool Item::isValid() bool Item::isValid()
{ {
return g_things.isValidDatId(m_id, DatItemCategory); return g_things.isValidDatId(m_id, ThingCategoryItem);
} }
void Item::unserializeItem(const BinaryTreePtr &in) void Item::unserializeItem(const BinaryTreePtr &in)
@ -277,10 +277,10 @@ ItemPtr Item::clone()
const ThingTypePtr& Item::getThingType() const ThingTypePtr& Item::getThingType()
{ {
return g_things.getThingType(m_id, DatItemCategory); return g_things.getThingType(m_id, ThingCategoryItem);
} }
ThingType* Item::rawGetThingType() ThingType* Item::rawGetThingType()
{ {
return g_things.rawGetThingType(m_id, DatItemCategory); return g_things.rawGetThingType(m_id, ThingCategoryItem);
} }

@ -28,7 +28,7 @@
#include "thing.h" #include "thing.h"
#include "itemtype.h" #include "itemtype.h"
enum AttrTypes_t enum ItemAttr : uint8
{ {
ATTR_END = 0, ATTR_END = 0,
//ATTR_DESCRIPTION = 1, //ATTR_DESCRIPTION = 1,

@ -29,14 +29,14 @@
ItemType::ItemType() ItemType::ItemType()
{ {
m_category = OtbInvalidCateogry; m_category = ItemCategoryInvalid;
} }
void ItemType::unserialize(const BinaryTreePtr& node) void ItemType::unserialize(const BinaryTreePtr& node)
{ {
m_null = false; m_null = false;
m_category = (OtbCategory)node->getU8(); m_category = (ItemCategory)node->getU8();
node->getU32(); // flags node->getU32(); // flags
@ -48,31 +48,26 @@ void ItemType::unserialize(const BinaryTreePtr& node)
uint16 len = node->getU16(); uint16 len = node->getU16();
switch(attr) { switch(attr) {
case OtbAttribServerId: { case ItemTypeAttrServerId: {
uint16 serverId = node->getU16(); uint16 serverId = node->getU16();
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) {
static ItemTypePtr dummyType(g_things.getNullItemType()); while(lastId != serverId - 1)
while(lastId != serverId - 1) { ++lastId;
dummyType->setServerId(++lastId);
g_things.addItemType(dummyType);
}
} }
assert(len == 2);
setServerId(serverId); setServerId(serverId);
break; break;
} }
case OtbAttribClientId: { case ItemTypeAttrClientId: {
setClientId(node->getU16()); setClientId(node->getU16());
assert(len == 2);
break; break;
} }
case OtbAttribName: { case ItemTypeAttrName: {
setName(node->getString()); setName(node->getString());
break; break;
} }
case OtbAttribDesc: { case ItemTypeAttrDesc: {
setDesc(node->getString()); setDesc(node->getString());
break; break;
} }

@ -29,57 +29,55 @@
#include <framework/xml/tinyxml.h> #include <framework/xml/tinyxml.h>
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>
enum ItemCategory {
enum OtbCategory { ItemCategoryInvalid = 0,
OtbInvalidCateogry = 0, ItemCategoryGround = 1,
OtbGround, ItemCategoryContainer = 2,
OtbContainer, ItemCategoryWeapon = 3,
OtbWeapon, ItemCategoryAmmunition = 4,
OtbAmmunition, ItemCategoryArmor = 5,
OtbArmor, ItemCategoryCharges = 6,
OtbCharges, ItemCategoryTeleport = 7,
OtbTeleport, ItemCategoryMagicField = 8,
OtbMagicField, ItemCategoryWritable = 9,
OtbWritable, ItemCategoryKey = 10,
OtbKey, ItemCategorySplash = 11,
OtbSplash, ItemCategoryFluid = 12,
OtbFluid, ItemCategoryDoor = 13,
OtbDoor, ItemCategoryLast = 14
OtbLastCategory
}; };
enum OtbAttrib { enum ItemTypeAttr : uint8 {
OtbAttribFirst = 0x10, ItemTypeAttrServerId = 16,
OtbAttribServerId = OtbAttribFirst, ItemTypeAttrClientId = 17,
OtbAttribClientId, ItemTypeAttrName = 18, // deprecated
OtbAttribName, // deprecated ItemTypeAttrDesc = 19, // deprecated
OtbAttribDesc, // deprecated ItemTypeAttrSpeed = 20,
OtbAttribSpeed, ItemTypeAttrSlot = 21, // deprecated
OtbAttribSlot, // deprecated ItemTypeAttrMaxItems = 22, // deprecated
OtbAttribMaxItems, // deprecated ItemTypeAttrWeight = 23, // deprecated
OtbAttribWeight, // deprecated ItemTypeAttrWeapon = 24, // deprecated
OtbAttribWeapon, // deprecated ItemTypeAttrAmmunition = 25, // deprecated
OtbAttribAmu, // deprecated ItemTypeAttrArmor = 26, // deprecated
OtbAttribArmor, // deprecated ItemTypeAttrMagicLevel = 27, // deprecated
OtbAttribMagLevel, // deprecated ItemTypeAttrMagicField = 28, // deprecated
OtbAttribMagicField, // deprecated ItemTypeAttrWritable = 29, // deprecated
OtbAttribWritable, // deprecated ItemTypeAttrRotateTo = 30, // deprecated
OtbAttribRotateTo, // deprecated ItemTypeAttrDecay = 31, // deprecated
OtbAttribDecay, // deprecated ItemTypeAttrSpriteHash = 32,
OtbAttribSpriteHash, ItemTypeAttrMinimapColor = 33,
OtbAttribMinimapColor, ItemTypeAttr07 = 34,
OtbAttrib07, ItemTypeAttr08 = 35,
OtbAttrib08, ItemTypeAttrLight = 36,
OtbAttribLight, ItemTypeAttrDecay2 = 37, // deprecated
OtbAttribDecay2, // deprecated ItemTypeAttrWeapon2 = 38, // deprecated
OtbAttribWeapon2, // deprecated ItemTypeAttrAmmunition2 = 39, // deprecated
OtbAttribAmu2, // deprecated ItemTypeAttrArmor2 = 40, // deprecated
OtbAttribArmor2, // deprecated ItemTypeAttrWritable2 = 41, // deprecated
OtbAttribWritable2, // deprecated ItemTypeAttrLight2 = 42,
OtbAttribLight2, ItemTypeAttrTopOrder = 43,
OtbAttribTopOrder, ItemTypeAttrWrtiable3 = 44, // deprecated
OtbAttribWrtiable3, // deprecated ItemTypeAttrLast = 45
OtbLastAttrib
}; };
class ItemType : public LuaObject class ItemType : public LuaObject
@ -89,21 +87,21 @@ public:
void unserialize(const BinaryTreePtr& node); void unserialize(const BinaryTreePtr& node);
uint16 getServerId() { return m_attribs.get<uint16>(OtbAttribServerId); } uint16 getServerId() { return m_attribs.get<uint16>(ItemTypeAttrServerId); }
uint16 getClientId() { return m_attribs.get<uint16>(OtbAttribClientId); } uint16 getClientId() { return m_attribs.get<uint16>(ItemTypeAttrClientId); }
OtbCategory getCategory() { return m_category; } ItemCategory getCategory() { return m_category; }
std::string getName() { return m_attribs.get<std::string>(OtbAttribName); } std::string getName() { return m_attribs.get<std::string>(ItemTypeAttrName); }
std::string getDesc() { return m_attribs.get<std::string>(OtbAttribDesc); } 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(OtbAttribClientId, clientId); } void setClientId(uint16 clientId) { m_attribs.set(ItemTypeAttrClientId, clientId); }
void setServerId(uint16 serverId) { m_attribs.set(OtbAttribServerId, serverId); } void setServerId(uint16 serverId) { m_attribs.set(ItemTypeAttrServerId, serverId); }
void setName(const std::string& name) { m_attribs.set(OtbAttribName, name); } void setName(const std::string& name) { m_attribs.set(ItemTypeAttrName, name); }
void setDesc(const std::string& desc) { m_attribs.set(OtbAttribDesc, desc); } void setDesc(const std::string& desc) { m_attribs.set(ItemTypeAttrDesc, desc); }
private: private:
OtbCategory m_category; ItemCategory m_category;
Boolean<true> m_null; Boolean<true> m_null;
AttribStorage m_attribs; AttribStorage m_attribs;

@ -54,6 +54,11 @@ void OTClient::registerLuaFunctions()
g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things); g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things);
g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things); g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things);
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", "getDatSignature", &ThingTypeManager::getDatSignature, &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", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
#if 0 #if 0
g_lua.registerSingletonClass("g_houses"); g_lua.registerSingletonClass("g_houses");
@ -211,7 +216,6 @@ void OTClient::registerLuaFunctions()
g_lua.registerClass<ProtocolGame, Protocol>(); g_lua.registerClass<ProtocolGame, Protocol>();
g_lua.bindClassStaticFunction<ProtocolGame>("create", []{ return ProtocolGamePtr(new ProtocolGame); }); g_lua.bindClassStaticFunction<ProtocolGame>("create", []{ return ProtocolGamePtr(new ProtocolGame); });
g_lua.bindClassMemberFunction<ProtocolGame>("login", &ProtocolGame::login); g_lua.bindClassMemberFunction<ProtocolGame>("login", &ProtocolGame::login);
g_lua.bindClassMemberFunction<ProtocolGame>("safeSend", &ProtocolGame::safeSend);
g_lua.bindClassMemberFunction<ProtocolGame>("sendExtendedOpcode", &ProtocolGame::sendExtendedOpcode); g_lua.bindClassMemberFunction<ProtocolGame>("sendExtendedOpcode", &ProtocolGame::sendExtendedOpcode);
g_lua.bindClassMemberFunction<ProtocolGame>("addPosition", &ProtocolGame::addPosition); g_lua.bindClassMemberFunction<ProtocolGame>("addPosition", &ProtocolGame::addPosition);
g_lua.bindClassMemberFunction<ProtocolGame>("setMapDescription", &ProtocolGame::setMapDescription); g_lua.bindClassMemberFunction<ProtocolGame>("setMapDescription", &ProtocolGame::setMapDescription);
@ -329,6 +333,13 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Creature>("asMonster", &Creature::asMonster); g_lua.bindClassMemberFunction<Creature>("asMonster", &Creature::asMonster);
g_lua.bindClassMemberFunction<Creature>("asNpc", &Creature::asNpc); g_lua.bindClassMemberFunction<Creature>("asNpc", &Creature::asNpc);
g_lua.registerClass<ItemType>();
g_lua.bindClassMemberFunction<ItemType>("getServerId", &ItemType::getServerId);
g_lua.bindClassMemberFunction<ItemType>("getClientId", &ItemType::getClientId);
g_lua.registerClass<ThingType>();
g_lua.bindClassMemberFunction<ThingType>("getMarketData", &ThingType::getMarketData);
g_lua.registerClass<Item, Thing>(); g_lua.registerClass<Item, Thing>();
g_lua.bindClassStaticFunction<Item>("create", &Item::create); g_lua.bindClassStaticFunction<Item>("create", &Item::create);
g_lua.bindClassMemberFunction<Item>("clone", &Item::clone); g_lua.bindClassMemberFunction<Item>("clone", &Item::clone);

@ -175,8 +175,7 @@ void Map::loadOtbm(const std::string& fileName)
break; break;
} }
default: { default: {
stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s", stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s", (int)tileAttr, stdext::to_string(pos)));
(int)tileAttr, stdext::pos_to_string(pos)));
} }
} }
} }
@ -203,8 +202,7 @@ void Map::loadOtbm(const std::string& fileName)
} }
if(house && item->isMoveable()) { if(house && item->isMoveable()) {
g_logger.warning(stdext::format("Movable item found in house: %d at pos %s - escaping...", item->getId(), g_logger.warning(stdext::format("Movable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos)));
stdext::pos_to_string(pos)));
item.reset(); item.reset();
} }

@ -32,7 +32,7 @@
#include <framework/core/clock.h> #include <framework/core/clock.h>
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>
enum OTBM_AttrTypes_t enum OTBM_ItemAttr
{ {
OTBM_ATTR_DESCRIPTION = 1, OTBM_ATTR_DESCRIPTION = 1,
OTBM_ATTR_EXT_FILE = 2, OTBM_ATTR_EXT_FILE = 2,

@ -83,17 +83,17 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition)
void Missile::setId(uint32 id) void Missile::setId(uint32 id)
{ {
if(!g_things.isValidDatId(id, DatMissileCategory)) if(!g_things.isValidDatId(id, ThingCategoryMissile))
id = 0; id = 0;
m_id = id; m_id = id;
} }
const ThingTypePtr& Missile::getThingType() const ThingTypePtr& Missile::getThingType()
{ {
return g_things.getThingType(m_id, DatMissileCategory); return g_things.getThingType(m_id, ThingCategoryMissile);
} }
ThingType* Missile::rawGetThingType() ThingType* Missile::rawGetThingType()
{ {
return g_things.rawGetThingType(m_id, DatMissileCategory); return g_things.rawGetThingType(m_id, ThingCategoryMissile);
} }

@ -24,7 +24,7 @@
Outfit::Outfit() Outfit::Outfit()
{ {
m_category = DatCreatureCategory; m_category = ThingCategoryCreature;
m_id = 0; m_id = 0;
resetClothes(); resetClothes();
} }

@ -45,7 +45,7 @@ public:
void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); } void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); }
void setAddons(int addons) { m_addons = addons; } void setAddons(int addons) { m_addons = addons; }
void setMount(int mount) { m_mount = mount; } void setMount(int mount) { m_mount = mount; }
void setCategory(DatCategory category) { m_category = category; } void setCategory(ThingCategory category) { m_category = category; }
void resetClothes(); void resetClothes();
@ -56,7 +56,7 @@ public:
int getFeet() const { return m_feet; } int getFeet() const { return m_feet; }
int getAddons() const { return m_addons; } int getAddons() const { return m_addons; }
int getMount() const { return m_mount; } int getMount() const { return m_mount; }
DatCategory getCategory() const { return m_category; } ThingCategory getCategory() const { return m_category; }
Color getHeadColor() const { return m_headColor; } Color getHeadColor() const { return m_headColor; }
Color getBodyColor() const { return m_bodyColor; } Color getBodyColor() const { return m_bodyColor; }
@ -64,7 +64,7 @@ public:
Color getFeetColor() const { return m_feetColor; } Color getFeetColor() const { return m_feetColor; }
private: private:
DatCategory m_category; ThingCategory m_category;
int m_id, m_head, m_body, m_legs, m_feet, m_addons, m_mount; int m_id, m_head, m_body, m_legs, m_feet, m_addons, m_mount;
Color m_headColor, m_bodyColor, m_legsColor, m_feetColor; Color m_headColor, m_bodyColor, m_legsColor, m_feetColor;
}; };

@ -32,17 +32,9 @@ class ProtocolGame : public Protocol
{ {
public: public:
void login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName); void login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName);
void safeSend(const OutputMessagePtr& outputMessage); void send(const OutputMessagePtr& outputMessage);
void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
protected: void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
void onConnect();
void onRecv(const InputMessagePtr& inputMessage);
void onError(const boost::system::error_code& error);
friend class Game;
protected:
void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom); void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom);
void sendLogout(); void sendLogout();
void sendPing(); void sendPing();
@ -113,6 +105,13 @@ protected:
void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation); void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation);
void sendRequestItemInfo(int itemId, int index); void sendRequestItemInfo(int itemId, int index);
protected:
void onConnect();
void onRecv(const InputMessagePtr& inputMessage);
void onError(const boost::system::error_code& error);
friend class Game;
public: public:
void addPosition(const OutputMessagePtr& msg, const Position& position); void addPosition(const OutputMessagePtr& msg, const Position& position);

@ -1316,7 +1316,7 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
int lookType = msg->getU16(); int lookType = msg->getU16();
if(lookType != 0) { if(lookType != 0) {
outfit.setCategory(DatCreatureCategory); outfit.setCategory(ThingCategoryCreature);
int head = msg->getU8(); int head = msg->getU8();
int body = msg->getU8(); int body = msg->getU8();
int legs = msg->getU8(); int legs = msg->getU8();
@ -1333,11 +1333,11 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
else { else {
int lookTypeEx = msg->getU16(); int lookTypeEx = msg->getU16();
if(lookTypeEx == 0) { if(lookTypeEx == 0) {
outfit.setCategory(DatEffectCategory); outfit.setCategory(ThingCategoryEffect);
outfit.setId(13); outfit.setId(13);
} }
else { else {
outfit.setCategory(DatItemCategory); outfit.setCategory(ThingCategoryItem);
outfit.setId(lookTypeEx); outfit.setId(lookTypeEx);
} }
} }

@ -23,7 +23,7 @@
#include "protocolgame.h" #include "protocolgame.h"
#include "game.h" #include "game.h"
void ProtocolGame::safeSend(const OutputMessagePtr& outputMessage) void ProtocolGame::send(const OutputMessagePtr& outputMessage)
{ {
// avoid usage of automated sends (bot modules) // avoid usage of automated sends (bot modules)
if(!g_game.checkBotProtection()) if(!g_game.checkBotProtection())
@ -38,7 +38,7 @@ void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer)
msg->addU8(Proto::ClientExtendedOpcode); msg->addU8(Proto::ClientExtendedOpcode);
msg->addU8(opcode); msg->addU8(opcode);
msg->addString(buffer); msg->addString(buffer);
safeSend(msg); send(msg);
} else { } else {
g_logger.error(stdext::format("Unable to send extended opcode %d, extended opcodes are not enabled", opcode)); g_logger.error(stdext::format("Unable to send extended opcode %d, extended opcodes are not enabled", opcode));
} }
@ -109,7 +109,7 @@ void ProtocolGame::sendPing()
{ {
OutputMessagePtr msg(new OutputMessage); OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientPing); msg->addU8(Proto::ClientPing);
send(msg); Protocol::send(msg);
} }
void ProtocolGame::sendPingBack() void ProtocolGame::sendPingBack()

@ -32,7 +32,7 @@
ThingType::ThingType() ThingType::ThingType()
{ {
m_category = DatInvalidCategory; m_category = ThingInvalidCategory;
m_id = 0; m_id = 0;
m_null = true; m_null = true;
m_exactSize = 0; m_exactSize = 0;
@ -41,43 +41,43 @@ ThingType::ThingType()
m_layers = 0; m_layers = 0;
} }
void ThingType::unserialize(uint16 clientId, DatCategory category, const FileStreamPtr& fin) void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin)
{ {
m_null = false; m_null = false;
m_id = clientId; m_id = clientId;
m_category = category; m_category = category;
bool done = false; bool done = false;
for(int i = 0 ; i < DatLastAttrib;++i) { for(int i = 0 ; i < ThingLastAttr;++i) {
int attrib = fin->getU8(); int attr = fin->getU8();
if(attrib == DatLastAttrib) { if(attr == ThingLastAttr) {
done = true; done = true;
break; break;
} }
if(g_game.getFeature(Otc::GameChargeableItems)) { if(g_game.getFeature(Otc::GameChargeableItems)) {
if(attrib == DatAttribWritable) { if(attr == ThingAttrWritable) {
m_attribs.set(DatAttribChargeable, true); m_attribs.set(ThingAttrChargeable, true);
continue; continue;
} else if(attrib > DatAttribWritable) } else if(attr > ThingAttrWritable)
attrib -= 1; attr -= 1;
} }
switch(attrib) { switch(attr) {
case DatAttribDisplacement: { case ThingAttrDisplacement: {
m_displacement.x = fin->getU16(); m_displacement.x = fin->getU16();
m_displacement.y = fin->getU16(); m_displacement.y = fin->getU16();
m_attribs.set(attrib, true); m_attribs.set(attr, true);
break; break;
} }
case DatAttribLight: { case ThingAttrLight: {
Light light; Light light;
light.intensity = fin->getU16(); light.intensity = fin->getU16();
light.color = fin->getU16(); light.color = fin->getU16();
m_attribs.set(attrib, light); m_attribs.set(attr, light);
break; break;
} }
case DatAttribMarket: { case ThingAttrMarket: {
MarketData market; MarketData market;
market.category = fin->getU16(); market.category = fin->getU16();
market.showAs = fin->getU16(); market.showAs = fin->getU16();
@ -85,20 +85,20 @@ void ThingType::unserialize(uint16 clientId, DatCategory category, const FileStr
market.name = fin->getString(); market.name = fin->getString();
market.restrictProfession = fin->getU16(); market.restrictProfession = fin->getU16();
market.requiredLevel = fin->getU16(); market.requiredLevel = fin->getU16();
m_attribs.set(attrib, market); m_attribs.set(attr, market);
break; break;
} }
case DatAttribGround: case ThingAttrGround:
case DatAttribWritable: case ThingAttrWritable:
case DatAttribWritableOnce: case ThingAttrWritableOnce:
case DatAttribElevation: case ThingAttrElevation:
case DatAttribMiniMapColor: case ThingAttrMinimapColor:
case DatAttribCloth: case ThingAttrCloth:
case DatAttribLensHelp: case ThingAttrLensHelp:
m_attribs.set(attrib, fin->getU16()); m_attribs.set(attr, fin->getU16());
break; break;
default: default:
m_attribs.set(attrib, true); m_attribs.set(attr, true);
break; break;
}; };
} }
@ -164,7 +164,7 @@ const TexturePtr& ThingType::getTexture(int animationPhase)
// we don't need layers in common items, they will be pre-drawn // we don't need layers in common items, they will be pre-drawn
int textureLayers = 1; int textureLayers = 1;
int numLayers = m_layers; int numLayers = m_layers;
if(m_category == DatCreatureCategory && numLayers >= 2) { if(m_category == ThingCategoryCreature && numLayers >= 2) {
// 5 layers: outfit base, red mask, green mask, blue mask, yellow mask // 5 layers: outfit base, red mask, green mask, blue mask, yellow mask
textureLayers = 5; textureLayers = 5;
numLayers = 5; numLayers = 5;
@ -182,7 +182,7 @@ const TexturePtr& ThingType::getTexture(int animationPhase)
for(int y = 0; y < m_numPatternY; ++y) { for(int y = 0; y < m_numPatternY; ++y) {
for(int x = 0; x < m_numPatternX; ++x) { for(int x = 0; x < m_numPatternX; ++x) {
for(int l = 0; l < numLayers; ++l) { for(int l = 0; l < numLayers; ++l) {
bool spriteMask = (m_category == DatCreatureCategory && l > 0); bool spriteMask = (m_category == ThingCategoryCreature && l > 0);
int frameIndex = getTextureIndex(l % textureLayers, x, y, z); int frameIndex = getTextureIndex(l % textureLayers, x, y, z);
Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(), Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(),
frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * Otc::TILE_PIXELS; frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * Otc::TILE_PIXELS;

@ -20,8 +20,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef THINGTYPEDAT_H #ifndef THINGTYPE_H
#define THINGTYPEDAT_H #define THINGTYPE_H
#include "declarations.h" #include "declarations.h"
#include <framework/core/declarations.h> #include <framework/core/declarations.h>
@ -31,63 +31,59 @@
#include <framework/net/server.h> #include <framework/net/server.h>
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>
enum DatCategory { enum ThingCategory : uint8 {
DatItemCategory = 0, ThingCategoryItem = 0,
DatCreatureCategory, ThingCategoryCreature,
DatEffectCategory, ThingCategoryEffect,
DatMissileCategory, ThingCategoryMissile,
DatLastCategory, ThingInvalidCategory,
DatInvalidCategory = DatLastCategory ThingLastCategory = ThingInvalidCategory
}; };
enum DatSpriteMask { enum ThingAttr : uint8 {
DatRedMask = 1, ThingAttrGround = 0,
DatGreenMask, ThingAttrGroundBorder = 1,
DatBlueMask, ThingAttrOnBottom = 2,
DatYellowMask, ThingAttrOnTop = 3,
DatLastMask ThingAttrContainer = 4,
ThingAttrStackable = 5,
ThingAttrForceUse = 6,
ThingAttrMultiUse = 7,
ThingAttrWritable = 8,
ThingAttrWritableOnce = 9,
ThingAttrFluidContainer = 10,
ThingAttrSplash = 11,
ThingAttrNotWalkable = 12,
ThingAttrNotMoveable = 13,
ThingAttrBlockProjectile = 14,
ThingAttrNotPathable = 15,
ThingAttrPickupable = 16,
ThingAttrHangable = 17,
ThingAttrHookSouth = 18,
ThingAttrHookEast = 19,
ThingAttrRotateable = 20,
ThingAttrLight = 21,
ThingAttrDontHide = 22,
ThingAttrTranslucent = 23,
ThingAttrDisplacement = 24,
ThingAttrElevation = 25,
ThingAttrLyingCorpse = 26,
ThingAttrAnimateAlways = 27,
ThingAttrMinimapColor = 28,
ThingAttrLensHelp = 29,
ThingAttrFullGround = 30,
ThingAttrLook = 31,
ThingAttrCloth = 32,
ThingAttrMarket = 33,
ThingAttrChargeable = 254, // deprecated
ThingLastAttr = 255,
}; };
enum DatAttrib { enum SpriteMask {
DatAttribGround = 0, SpriteMaskRed = 1,
DatAttribGroundBorder, SpriteMaskGreen,
DatAttribOnBottom, SpriteMaskBlue,
DatAttribOnTop, SpriteMaskYellow
DatAttribContainer,
DatAttribStackable,
DatAttribForceUse,
DatAttribMultiUse,
//DatAttribRune
DatAttribWritable,
DatAttribWritableOnce,
DatAttribFluidContainer,
DatAttribSplash,
DatAttribNotWalkable,
DatAttribNotMoveable,
DatAttribBlockProjectile,
DatAttribNotPathable,
DatAttribPickupable,
DatAttribHangable,
DatAttribHookSouth,
DatAttribHookEast,
DatAttribRotateable,
DatAttribLight,
DatAttribDontHide,
DatAttribTranslucent,
DatAttribDisplacement,
DatAttribElevation,
DatAttribLyingCorpse,
DatAttribAnimateAlways,
DatAttribMiniMapColor,
DatAttribLensHelp,
DatAttribFullGround,
DatAttribIgnoreLook,
DatAttribCloth,
DatAttribMarket,
DatLastAttrib = 255,
// legacy attribs
DatAttribChargeable = 254
}; };
struct MarketData { struct MarketData {
@ -109,13 +105,14 @@ class ThingType : public LuaObject
public: public:
ThingType(); ThingType();
void unserialize(uint16 clientId, DatCategory category, const FileStreamPtr& fin); void unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin);
void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase); void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase);
uint16 getId() { return m_id; } uint16 getId() { return m_id; }
DatCategory getCategory() { return m_category; } ThingCategory getCategory() { return m_category; }
bool isNull() { return m_null; } bool isNull() { return m_null; }
bool hasAttr(ThingAttr attr) { return m_attribs.has(attr); }
Size getSize() { return m_size; } Size getSize() { return m_size; }
int getWidth() { return m_size.width(); } int getWidth() { return m_size.width(); }
@ -130,49 +127,49 @@ public:
int getDisplacementX() { return getDisplacement().x; } int getDisplacementX() { return getDisplacement().x; }
int getDisplacementY() { return getDisplacement().y; } int getDisplacementY() { return getDisplacement().y; }
int getGroundSpeed() { return m_attribs.get<uint16>(DatAttribGround); } int getGroundSpeed() { return m_attribs.get<uint16>(ThingAttrGround); }
int getMaxTextLength() { return m_attribs.has(DatAttribWritableOnce) ? m_attribs.get<uint16>(DatAttribWritableOnce) : m_attribs.get<uint16>(DatAttribWritable); } int getMaxTextLength() { return m_attribs.has(ThingAttrWritableOnce) ? m_attribs.get<uint16>(ThingAttrWritableOnce) : m_attribs.get<uint16>(ThingAttrWritable); }
Light getLight() { return m_attribs.get<Light>(DatAttribLight); } Light getLight() { return m_attribs.get<Light>(ThingAttrLight); }
int getMinimapColor() { return m_attribs.get<uint16>(DatAttribMiniMapColor); } int getMinimapColor() { return m_attribs.get<uint16>(ThingAttrMinimapColor); }
int getLensHelp() { return m_attribs.get<uint16>(DatAttribLensHelp); } int getLensHelp() { return m_attribs.get<uint16>(ThingAttrLensHelp); }
int getClothSlot() { return m_attribs.get<uint16>(DatAttribCloth); } int getClothSlot() { return m_attribs.get<uint16>(ThingAttrCloth); }
int getElevation() { return m_attribs.get<uint16>(DatAttribElevation); } int getElevation() { return m_attribs.get<uint16>(ThingAttrElevation); }
MarketData getMarketData() { return m_attribs.get<MarketData>(DatAttribMarket); } MarketData getMarketData() { return m_attribs.get<MarketData>(ThingAttrMarket); }
bool isGround() { return m_attribs.has(DatAttribGround); } bool isGround() { return m_attribs.has(ThingAttrGround); }
bool isGroundBorder() { return m_attribs.has(DatAttribGroundBorder); } bool isGroundBorder() { return m_attribs.has(ThingAttrGroundBorder); }
bool isOnBottom() { return m_attribs.has(DatAttribOnBottom); } bool isOnBottom() { return m_attribs.has(ThingAttrOnBottom); }
bool isOnTop() { return m_attribs.has(DatAttribOnTop); } bool isOnTop() { return m_attribs.has(ThingAttrOnTop); }
bool isContainer() { return m_attribs.has(DatAttribContainer); } bool isContainer() { return m_attribs.has(ThingAttrContainer); }
bool isStackable() { return m_attribs.has(DatAttribStackable); } bool isStackable() { return m_attribs.has(ThingAttrStackable); }
bool isForceUse() { return m_attribs.has(DatAttribForceUse); } bool isForceUse() { return m_attribs.has(ThingAttrForceUse); }
bool isMultiUse() { return m_attribs.has(DatAttribMultiUse); } bool isMultiUse() { return m_attribs.has(ThingAttrMultiUse); }
bool isWritable() { return m_attribs.has(DatAttribWritable); } bool isWritable() { return m_attribs.has(ThingAttrWritable); }
bool isChargeable() { return m_attribs.has(DatAttribChargeable); } bool isChargeable() { return m_attribs.has(ThingAttrChargeable); }
bool isWritableOnce() { return m_attribs.has(DatAttribWritableOnce); } bool isWritableOnce() { return m_attribs.has(ThingAttrWritableOnce); }
bool isFluidContainer() { return m_attribs.has(DatAttribFluidContainer); } bool isFluidContainer() { return m_attribs.has(ThingAttrFluidContainer); }
bool isSplash() { return m_attribs.has(DatAttribSplash); } bool isSplash() { return m_attribs.has(ThingAttrSplash); }
bool isNotWalkable() { return m_attribs.has(DatAttribNotWalkable); } bool isNotWalkable() { return m_attribs.has(ThingAttrNotWalkable); }
bool isNotMoveable() { return m_attribs.has(DatAttribNotMoveable); } bool isNotMoveable() { return m_attribs.has(ThingAttrNotMoveable); }
bool blockProjectile() { return m_attribs.has(DatAttribBlockProjectile); } bool blockProjectile() { return m_attribs.has(ThingAttrBlockProjectile); }
bool isNotPathable() { return m_attribs.has(DatAttribNotPathable); } bool isNotPathable() { return m_attribs.has(ThingAttrNotPathable); }
bool isPickupable() { return m_attribs.has(DatAttribPickupable); } bool isPickupable() { return m_attribs.has(ThingAttrPickupable); }
bool isHangable() { return m_attribs.has(DatAttribHangable); } bool isHangable() { return m_attribs.has(ThingAttrHangable); }
bool isHookSouth() { return m_attribs.has(DatAttribHookSouth); } bool isHookSouth() { return m_attribs.has(ThingAttrHookSouth); }
bool isHookEast() { return m_attribs.has(DatAttribHookEast); } bool isHookEast() { return m_attribs.has(ThingAttrHookEast); }
bool isRotateable() { return m_attribs.has(DatAttribRotateable); } bool isRotateable() { return m_attribs.has(ThingAttrRotateable); }
bool hasLight() { return m_attribs.has(DatAttribLight); } bool hasLight() { return m_attribs.has(ThingAttrLight); }
bool isDontHide() { return m_attribs.has(DatAttribDontHide); } bool isDontHide() { return m_attribs.has(ThingAttrDontHide); }
bool isTranslucent() { return m_attribs.has(DatAttribTranslucent); } bool isTranslucent() { return m_attribs.has(ThingAttrTranslucent); }
bool hasDisplacement() { return m_attribs.has(DatAttribDisplacement); } bool hasDisplacement() { return m_attribs.has(ThingAttrDisplacement); }
bool hasElevation() { return m_attribs.has(DatAttribElevation); } bool hasElevation() { return m_attribs.has(ThingAttrElevation); }
bool isLyingCorpse() { return m_attribs.has(DatAttribLyingCorpse); } bool isLyingCorpse() { return m_attribs.has(ThingAttrLyingCorpse); }
bool isAnimateAlways() { return m_attribs.has(DatAttribAnimateAlways); } bool isAnimateAlways() { return m_attribs.has(ThingAttrAnimateAlways); }
bool hasMiniMapColor() { return m_attribs.has(DatAttribMiniMapColor); } bool hasMiniMapColor() { return m_attribs.has(ThingAttrMinimapColor); }
bool hasLensHelp() { return m_attribs.has(DatAttribLensHelp); } bool hasLensHelp() { return m_attribs.has(ThingAttrLensHelp); }
bool isFullGround() { return m_attribs.has(DatAttribFullGround); } bool isFullGround() { return m_attribs.has(ThingAttrFullGround); }
bool isIgnoreLook() { return m_attribs.has(DatAttribIgnoreLook); } bool isIgnoreLook() { return m_attribs.has(ThingAttrLook); }
bool isCloth() { return m_attribs.has(DatAttribCloth); } bool isCloth() { return m_attribs.has(ThingAttrCloth); }
bool isMarketable() { return m_attribs.has(DatAttribMarket); } bool isMarketable() { return m_attribs.has(ThingAttrMarket); }
private: private:
const TexturePtr& getTexture(int animationPhase); const TexturePtr& getTexture(int animationPhase);
@ -180,7 +177,7 @@ private:
uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a); uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a);
uint getTextureIndex(int l, int x, int y, int z); uint getTextureIndex(int l, int x, int y, int z);
DatCategory m_category; ThingCategory m_category;
uint16 m_id; uint16 m_id;
bool m_null; bool m_null;
AttribStorage m_attribs; AttribStorage m_attribs;

@ -43,16 +43,16 @@ void ThingTypeManager::init()
m_datLoaded = false; m_datLoaded = false;
m_xmlLoaded = false; m_xmlLoaded = false;
m_otbLoaded = false; m_otbLoaded = false;
for(int i = 0; i < DatLastCategory; ++i) for(int i = 0; i < ThingLastCategory; ++i)
m_datTypes[i].resize(1, m_nullThingType); m_thingTypes[i].resize(1, m_nullThingType);
m_otbTypes.resize(1, m_nullItemType); m_itemTypes.resize(1, m_nullItemType);
} }
void ThingTypeManager::terminate() void ThingTypeManager::terminate()
{ {
for(int i = 0; i < DatLastCategory; ++i) for(int i = 0; i < ThingLastCategory; ++i)
m_datTypes[i].clear(); m_thingTypes[i].clear();
m_otbTypes.clear(); m_itemTypes.clear();
m_nullThingType = nullptr; m_nullThingType = nullptr;
m_nullItemType = nullptr; m_nullItemType = nullptr;
} }
@ -66,20 +66,20 @@ bool ThingTypeManager::loadDat(const std::string& file)
m_datSignature = fin->getU32(); m_datSignature = fin->getU32();
int numThings[DatLastCategory]; int numThings[ThingLastCategory];
for(int category = 0; category < DatLastCategory; ++category) { for(int category = 0; category < ThingLastCategory; ++category) {
int count = fin->getU16() + 1; int count = fin->getU16() + 1;
m_datTypes[category].resize(count, m_nullThingType); m_thingTypes[category].resize(count, m_nullThingType);
} }
for(int category = 0; category < DatLastCategory; ++category) { for(int category = 0; category < ThingLastCategory; ++category) {
uint16 firstId = 1; uint16 firstId = 1;
if(category == DatItemCategory) if(category == ThingCategoryItem)
firstId = 100; firstId = 100;
for(uint16 id = firstId; id < m_datTypes[category].size(); ++id) { for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id) {
ThingTypePtr type(new ThingType); ThingTypePtr type(new ThingType);
type->unserialize(id, (DatCategory)category, fin); type->unserialize(id, (ThingCategory)category, fin);
m_datTypes[category][id] = type; m_thingTypes[category][id] = type;
} }
} }
@ -112,7 +112,7 @@ void ThingTypeManager::loadOtb(const std::string& file)
root->getU32(); // build number root->getU32(); // build number
root->skip(128); // description root->skip(128); // description
m_otbTypes.resize(root->getChildren().size(), m_nullItemType); m_itemTypes.resize(root->getChildren().size(), m_nullItemType);
for(const BinaryTreePtr& node : root->getChildren()) { for(const BinaryTreePtr& node : root->getChildren()) {
ItemTypePtr otbType(new ItemType); ItemTypePtr otbType(new ItemType);
otbType->unserialize(node); otbType->unserialize(node);
@ -187,17 +187,17 @@ void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
void ThingTypeManager::addItemType(const ItemTypePtr& otbType) void ThingTypeManager::addItemType(const ItemTypePtr& otbType)
{ {
uint16 id = otbType->getServerId(); uint16 id = otbType->getServerId();
if(m_otbTypes.size() <= id) if(m_itemTypes.size() <= id)
m_otbTypes.resize(id+1, m_nullItemType); m_itemTypes.resize(id+1, m_nullItemType);
m_otbTypes[id] = otbType; m_itemTypes[id] = otbType;
} }
const ItemTypePtr& ThingTypeManager::findOtbForClientId(uint16 id) const ItemTypePtr& ThingTypeManager::findOtbForClientId(uint16 id)
{ {
if(m_otbTypes.empty()) if(m_itemTypes.empty())
return m_nullItemType; return m_nullItemType;
for(const ItemTypePtr& otbType : m_otbTypes) { for(const ItemTypePtr& otbType : m_itemTypes) {
if(otbType->getClientId() == id) if(otbType->getClientId() == id)
return otbType; return otbType;
} }
@ -205,21 +205,46 @@ const ItemTypePtr& ThingTypeManager::findOtbForClientId(uint16 id)
return m_nullItemType; return m_nullItemType;
} }
const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, DatCategory category) const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory category)
{ {
if(category >= DatLastCategory || id >= m_datTypes[category].size()) { if(category >= ThingLastCategory || id >= m_thingTypes[category].size()) {
g_logger.error(stdext::format("invalid thing type client id %d in category %d", id, category)); g_logger.error(stdext::format("invalid thing type client id %d in category %d", id, category));
return m_nullThingType; return m_nullThingType;
} }
return m_datTypes[category][id]; return m_thingTypes[category][id];
} }
const ItemTypePtr& ThingTypeManager::getItemType(uint16 id) const ItemTypePtr& ThingTypeManager::getItemType(uint16 id)
{ {
if(id >= m_otbTypes.size()) { if(id >= m_itemTypes.size()) {
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_otbTypes[id]; return m_itemTypes[id];
} }
ThingTypeList ThingTypeManager::findThingTypeByAttr(ThingAttr attr, ThingCategory category)
{
ThingTypeList ret;
for(const ThingTypePtr& type : m_thingTypes[category])
if(type->hasAttr(attr))
ret.push_back(type);
return ret;
}
ItemTypeList ThingTypeManager::findItemTypeByCategory(ItemCategory category)
{
ItemTypeList ret;
for(const ItemTypePtr& type : m_itemTypes)
if(type->getCategory() == category)
ret.push_back(type);
return ret;
}
const ThingTypeList& ThingTypeManager::getThingTypes(ThingCategory category)
{
ThingTypeList ret;
if(category >= ThingLastCategory)
stdext::throw_exception(stdext::format("invalid thing type category %d", category));
return m_thingTypes[category];
}

@ -46,10 +46,16 @@ public:
const ThingTypePtr& getNullThingType() { return m_nullThingType; } const ThingTypePtr& getNullThingType() { return m_nullThingType; }
const ItemTypePtr& getNullItemType() { return m_nullItemType; } const ItemTypePtr& getNullItemType() { return m_nullItemType; }
const ThingTypePtr& getThingType(uint16 id, DatCategory category); const ThingTypePtr& getThingType(uint16 id, ThingCategory category);
const ItemTypePtr& getItemType(uint16 id); const ItemTypePtr& getItemType(uint16 id);
ThingType* rawGetThingType(uint16 id, DatCategory category) { return m_datTypes[category][id].get(); } ThingType* rawGetThingType(uint16 id, ThingCategory category) { return m_thingTypes[category][id].get(); }
ItemType* rawGetItemType(uint16 id) { return m_otbTypes[id].get(); } ItemType* rawGetItemType(uint16 id) { return m_itemTypes[id].get(); }
ThingTypeList findThingTypeByAttr(ThingAttr attr, ThingCategory category);
ItemTypeList findItemTypeByCategory(ItemCategory category);
const ThingTypeList& getThingTypes(ThingCategory category);
const ItemTypeList& getItemTypes() { return m_itemTypes; }
uint32 getDatSignature() { return m_datSignature; } uint32 getDatSignature() { return m_datSignature; }
uint32 getOtbMajorVersion() { return m_otbMajorVersion; } uint32 getOtbMajorVersion() { return m_otbMajorVersion; }
@ -59,12 +65,12 @@ public:
bool isXmlLoaded() { return m_xmlLoaded; } bool isXmlLoaded() { return m_xmlLoaded; }
bool isOtbLoaded() { return m_otbLoaded; } bool isOtbLoaded() { return m_otbLoaded; }
bool isValidDatId(uint16 id, DatCategory category) { return id >= 1 && id < m_datTypes[category].size(); } bool isValidDatId(uint16 id, ThingCategory category) { return id >= 1 && id < m_thingTypes[category].size(); }
bool isValidOtbId(uint16 id) { return id >= 1 && id < m_otbTypes.size(); } bool isValidOtbId(uint16 id) { return id >= 1 && id < m_itemTypes.size(); }
private: private:
ThingTypeList m_datTypes[DatLastCategory]; ThingTypeList m_thingTypes[ThingLastCategory];
ItemTypeList m_otbTypes; ItemTypeList m_itemTypes;
ThingTypePtr m_nullThingType; ThingTypePtr m_nullThingType;
ItemTypePtr m_nullItemType; ItemTypePtr m_nullItemType;

Loading…
Cancel
Save