From 96c363d997df3d2e2fcf8730a630cec2b0594dfc Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 21 Jun 2012 14:54:20 -0300 Subject: [PATCH] changes for otb compability --- modules/game/protocollogin.lua | 4 +- modules/game_tibiafiles/tibiafiles.otmod | 4 +- src/framework/core/filestream.cpp | 44 +-- src/framework/core/filestream.h | 10 +- src/otclient/CMakeLists.txt | 12 +- src/otclient/const.h | 2 +- src/otclient/core/creature.cpp | 26 +- src/otclient/core/declarations.h | 14 +- src/otclient/core/effect.cpp | 4 +- src/otclient/core/game.cpp | 2 +- src/otclient/core/item.cpp | 34 +- src/otclient/core/item.h | 2 +- src/otclient/core/itemloader.h | 119 ------- src/otclient/core/map.cpp | 36 ++- src/otclient/core/map.h | 10 +- src/otclient/core/missile.cpp | 6 +- src/otclient/core/outfit.cpp | 2 +- src/otclient/core/outfit.h | 8 +- src/otclient/core/spritemanager.cpp | 17 +- src/otclient/core/spritemanager.h | 4 +- src/otclient/core/thing.cpp | 5 +- src/otclient/core/thing.h | 103 +++--- src/otclient/core/thingstype.cpp | 168 ---------- src/otclient/core/thingtype.cpp | 166 ---------- src/otclient/core/thingtype.h | 157 --------- src/otclient/core/thingtypedat.cpp | 392 +++++++++++++++++++++++ src/otclient/core/thingtypedat.h | 235 ++++++++++++++ src/otclient/core/thingtypemanager.cpp | 261 +++++++++++++++ src/otclient/core/thingtypemanager.h | 81 +++++ src/otclient/core/thingtypeotb.cpp | 68 ++++ src/otclient/core/thingtypeotb.h | 103 ++++++ src/otclient/core/tile.cpp | 8 +- src/otclient/luafunctions.cpp | 23 +- src/otclient/net/protocolgameparse.cpp | 10 +- src/otclient/otclient.cpp | 7 +- 35 files changed, 1355 insertions(+), 792 deletions(-) delete mode 100644 src/otclient/core/itemloader.h delete mode 100644 src/otclient/core/thingstype.cpp delete mode 100644 src/otclient/core/thingtype.cpp delete mode 100644 src/otclient/core/thingtype.h create mode 100644 src/otclient/core/thingtypedat.cpp create mode 100644 src/otclient/core/thingtypedat.h create mode 100644 src/otclient/core/thingtypemanager.cpp create mode 100644 src/otclient/core/thingtypemanager.h create mode 100644 src/otclient/core/thingtypeotb.cpp create mode 100644 src/otclient/core/thingtypeotb.h diff --git a/modules/game/protocollogin.lua b/modules/game/protocollogin.lua index ff327976..f7e5daa9 100644 --- a/modules/game/protocollogin.lua +++ b/modules/game/protocollogin.lua @@ -7,8 +7,8 @@ local function sendLoginPacket(protocol) msg:addU16(1) -- todo: ClientOs msg:addU16(g_game.getClientVersion()) - msg:addU32(g_thingsType.getSignature()) - msg:addU32(g_sprites.getSignature()) + msg:addU32(g_things.getDatSignature()) + msg:addU32(g_sprites.getSprSignature()) msg:addU32(0) -- todo: pic signature local paddingBytes = 128 diff --git a/modules/game_tibiafiles/tibiafiles.otmod b/modules/game_tibiafiles/tibiafiles.otmod index ebfc3ff3..9e4f023f 100644 --- a/modules/game_tibiafiles/tibiafiles.otmod +++ b/modules/game_tibiafiles/tibiafiles.otmod @@ -4,9 +4,9 @@ Module reloadable: false @onLoad: | - if not g_thingsType.load('/game_tibiafiles/Tibia.dat') then + if not g_things.loadDat('/game_tibiafiles/Tibia.dat') then fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat")) end - if not g_sprites.load('/game_tibiafiles/Tibia.spr') then + if not g_sprites.loadSpr('/game_tibiafiles/Tibia.spr') then fatal(tr("Unable to load spr file, please place a valid Tibia spr in modules/game_tibiafiles/Tibia.spr")) end diff --git a/src/framework/core/filestream.cpp b/src/framework/core/filestream.cpp index e1d3466f..e7e06f5d 100644 --- a/src/framework/core/filestream.cpp +++ b/src/framework/core/filestream.cpp @@ -137,7 +137,7 @@ bool FileStream::seek(int pos) int FileStream::size() { - if(m_fileHandle) + if(m_fileHandle) return PHYSFS_fileLength(m_fileHandle); else return m_cacheBuffer.size(); @@ -249,28 +249,30 @@ std::string FileStream::getString() return str; } -uint8 FileStream::readNode(uint8 &oldNode, uint32 &type) +uint8 FileStream::readFirstNode(uint32& type) { - if (!oldNode) { - if ((oldNode = getU8()) == 0xFE) { - type = getU32(); - return oldNode; - } else { - dump << "Failed to read new node."; - return 0; - } - } - - assert(getU8() == 0xFF); - if ((oldNode = getU8()) == 0xFE) { - type = getU32(); - return oldNode; - } else { - dump << "Failed to read node with old type: " << type; - return 0; - } + dump << "first"; + uint8 node = getU8(); + if(node != NODE_START) + stdext::throw_exception("failed to read first node"); + type = getU32(); + return node; +} - return 0; +uint8 FileStream::readNextNode(uint8 oldNode, uint32& type) +{ + dump << "next"; + // end of old node + if(getU8() != NODE_END) + stdext::throw_exception("node not ended"); + + // next node + uint8 node = getU8(); + if(oldNode != NODE_START) + stdext::throw_exception("invalid node start"); + + type = getU32(); + return node; } void FileStream::addU8(uint8 v) diff --git a/src/framework/core/filestream.h b/src/framework/core/filestream.h index 8e0e31e7..523f7bc0 100644 --- a/src/framework/core/filestream.h +++ b/src/framework/core/filestream.h @@ -29,6 +29,12 @@ struct PHYSFS_File; class FileStream { + enum { + NODE_START = 0xFE, + NODE_END = 0xFF, + ESCAPE_CHAR = 0xFD, + }; + protected: FileStream(const std::string& name, PHYSFS_File *fileHandle); @@ -59,7 +65,9 @@ public: void addU32(uint8 v); void addU64(uint8 v); - uint8 readNode(uint8 &oldNode, uint32 &type); + uint8 readFirstNode(uint32& type); + uint8 readNextNode(uint8 oldNode, uint32& type); + private: std::string m_name; PHYSFS_File *m_fileHandle; diff --git a/src/otclient/CMakeLists.txt b/src/otclient/CMakeLists.txt index ddd175c3..693778bf 100644 --- a/src/otclient/CMakeLists.txt +++ b/src/otclient/CMakeLists.txt @@ -48,8 +48,6 @@ SET(otclient_SOURCES ${otclient_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/core/shadermanager.h ${CMAKE_CURRENT_LIST_DIR}/core/item.cpp ${CMAKE_CURRENT_LIST_DIR}/core/item.h - ${CMAKE_CURRENT_LIST_DIR}/core/itemloader.cpp - ${CMAKE_CURRENT_LIST_DIR}/core/itemloader.h ${CMAKE_CURRENT_LIST_DIR}/core/localplayer.cpp ${CMAKE_CURRENT_LIST_DIR}/core/localplayer.h ${CMAKE_CURRENT_LIST_DIR}/core/map.cpp @@ -68,10 +66,12 @@ SET(otclient_SOURCES ${otclient_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/core/statictext.h ${CMAKE_CURRENT_LIST_DIR}/core/thing.cpp ${CMAKE_CURRENT_LIST_DIR}/core/thing.h - ${CMAKE_CURRENT_LIST_DIR}/core/thingstype.cpp - ${CMAKE_CURRENT_LIST_DIR}/core/thingstype.h - ${CMAKE_CURRENT_LIST_DIR}/core/thingtype.cpp - ${CMAKE_CURRENT_LIST_DIR}/core/thingtype.h + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypemanager.cpp + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypemanager.h + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypedat.cpp + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypedat.h + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypeotb.cpp + ${CMAKE_CURRENT_LIST_DIR}/core/thingtypeotb.h ${CMAKE_CURRENT_LIST_DIR}/core/tile.cpp ${CMAKE_CURRENT_LIST_DIR}/core/tile.h diff --git a/src/otclient/const.h b/src/otclient/const.h index 6da38ff3..f403af58 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -84,7 +84,7 @@ namespace Otc DatFluidContainer, DatSplash, DatBlockWalk, - DatNotMovable, + DatNotMoveable, DatBlockProjectile, DatBlockPathFind, DatPickupable, diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 1022ba4f..84c3af53 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -21,7 +21,7 @@ */ #include "creature.h" -#include "thingstype.h" +#include "thingtypemanager.h" #include "localplayer.h" #include "map.h" #include "tile.h" @@ -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) { // outfit is a real creature - if(m_outfit.getCategory() == ThingsType::Creature) { + if(m_outfit.getCategory() == DatCreatureCategory) { int animationPhase = animateWalk ? m_walkAnimationPhase : 0; if(isAnimateAlways() && animateIdle) { @@ -107,26 +107,26 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani xPattern = direction; // yPattern => creature addon - for(int yPattern = 0; yPattern < getNumPatternsY(); yPattern++) { + for(int yPattern = 0; yPattern < getNumPatternY(); yPattern++) { // continue if we dont have this addon if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1)))) continue; - m_type->draw(dest, scaleFactor, 0, xPattern, yPattern, 0, animationPhase); + m_datType->draw(dest, scaleFactor, 0, xPattern, yPattern, 0, animationPhase); if(getLayers() > 1) { Color oldColor = g_painter->getColor(); Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); g_painter->setCompositionMode(Painter::CompositionMode_Multiply); g_painter->setColor(m_outfit.getHeadColor()); - m_type->draw(dest, scaleFactor, ThingType::YellowMask, xPattern, yPattern, 0, animationPhase); + m_datType->draw(dest, scaleFactor, DatYellowMask, xPattern, yPattern, 0, animationPhase); g_painter->setColor(m_outfit.getBodyColor()); - m_type->draw(dest, scaleFactor, ThingType::RedMask, xPattern, yPattern, 0, animationPhase); + m_datType->draw(dest, scaleFactor, DatRedMask, xPattern, yPattern, 0, animationPhase); g_painter->setColor(m_outfit.getLegsColor()); - m_type->draw(dest, scaleFactor, ThingType::GreenMask, xPattern, yPattern, 0, animationPhase); + m_datType->draw(dest, scaleFactor, DatGreenMask, xPattern, yPattern, 0, animationPhase); g_painter->setColor(m_outfit.getFeetColor()); - m_type->draw(dest, scaleFactor, ThingType::BlueMask, xPattern, yPattern, 0, animationPhase); + m_datType->draw(dest, scaleFactor, DatBlueMask, xPattern, yPattern, 0, animationPhase); g_painter->setColor(oldColor); g_painter->setCompositionMode(oldComposition); } @@ -139,7 +139,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, // instead we should loop in the phases between - if(m_outfit.getCategory() == ThingsType::Effect) { + if(m_outfit.getCategory() == DatEffectCategory) { animationPhases = std::max(1, animationPhases-2); animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME; } @@ -151,10 +151,10 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani animationPhase = animationPhases-1; } - if(m_outfit.getCategory() == ThingsType::Effect) + if(m_outfit.getCategory() == DatEffectCategory) animationPhase = std::min(animationPhase+1, getAnimationPhases()); - m_type->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); + m_datType->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); } } @@ -301,7 +301,7 @@ void Creature::stopWalk() void Creature::updateWalkAnimation(int totalPixelsWalked) { // update outfit animation - if(m_outfit.getCategory() != ThingsType::Creature) + if(m_outfit.getCategory() != DatCreatureCategory) return; int footAnimPhases = getAnimationPhases() - 1; @@ -459,7 +459,7 @@ void Creature::setOutfit(const Outfit& outfit) { m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed. m_outfit = outfit; - m_type = g_thingsType.getThingType(outfit.getId(), outfit.getCategory()); + m_datType = g_things.getDatType(outfit.getId(), outfit.getCategory()); } void Creature::setSkull(uint8 skull) diff --git a/src/otclient/core/declarations.h b/src/otclient/core/declarations.h index a0a65989..78dd4ccb 100644 --- a/src/otclient/core/declarations.h +++ b/src/otclient/core/declarations.h @@ -41,16 +41,13 @@ class Effect; class Missile; class AnimatedText; class StaticText; -class ThingType; -class ThingsType; -class ItemShader; -class ItemData; +class ThingTypeDat; +class ThingTypeOtb; typedef std::shared_ptr MapViewPtr; typedef std::shared_ptr TilePtr; typedef std::shared_ptr ThingPtr; typedef std::shared_ptr ItemPtr; -typedef std::shared_ptr ItemDataPtr; typedef std::shared_ptr ContainerPtr; typedef std::shared_ptr CreaturePtr; typedef std::shared_ptr MonsterPtr; @@ -61,10 +58,11 @@ typedef std::shared_ptr EffectPtr; typedef std::shared_ptr MissilePtr; typedef std::shared_ptr AnimatedTextPtr; typedef std::shared_ptr StaticTextPtr; -typedef std::shared_ptr ItemShaderPtr; +typedef std::shared_ptr ThingTypeDatPtr; +typedef std::shared_ptr ThingTypeOtbPtr; typedef std::vector ThingList; -typedef std::vector ThingTypeList; -typedef std::vector ItemDataList; +typedef std::vector ThingTypeDatList; +typedef std::vector ThingTypeOtbList; #endif diff --git a/src/otclient/core/effect.cpp b/src/otclient/core/effect.cpp index 1ea7b45e..359e8846 100644 --- a/src/otclient/core/effect.cpp +++ b/src/otclient/core/effect.cpp @@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate) int animationPhase = 0; if(animate) animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1); - m_type->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); + m_datType->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); } void Effect::startAnimation() @@ -47,5 +47,5 @@ void Effect::startAnimation() void Effect::setId(uint32 id) { m_id = id; - m_type = g_thingsType.getThingType(m_id, ThingsType::Effect); + m_datType = g_things.getDatType(m_id, DatEffectCategory); } diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index b3dbdc4f..c849f2bd 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -605,7 +605,7 @@ void Game::use(const ThingPtr& thing) void Game::useInventoryItem(int itemId) { - if(!canPerformGameAction() || !g_thingsType.isValidItemId(itemId)) + if(!canPerformGameAction() || !g_things.isValidDatId(itemId, DatItemCategory)) return; Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index c8f86833..f932e882 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -21,7 +21,7 @@ */ #include "item.h" -#include "thingstype.h" +#include "thingtypemanager.h" #include "spritemanager.h" #include "thing.h" #include "tile.h" @@ -42,11 +42,7 @@ Item::Item() : Thing() ItemPtr Item::create(int id) { ItemPtr item = ItemPtr(new Item); - if(id < g_thingsType.getFirstItemId() || id > g_thingsType.getMaxItemid()) - g_logger.traceError(stdext::format("invalid item id %d", id)); - else { - item->setId(id); - } + item->setId(id); return item; } @@ -66,7 +62,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) // determine x,y,z patterns int xPattern = 0, yPattern = 0, zPattern = 0; - if(isStackable() && getNumPatternsX() == 4 && getNumPatternsY() == 2) { + if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) { if(m_countOrSubType <= 0) { xPattern = 0; yPattern = 0; @@ -90,9 +86,9 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) const TilePtr& tile = getTile(); if(tile) { if(tile->mustHookSouth()) - xPattern = getNumPatternsX() >= 2 ? 1 : 0; + xPattern = getNumPatternX() >= 2 ? 1 : 0; else if(tile->mustHookEast()) - xPattern = getNumPatternsX() >= 3 ? 2 : 0; + xPattern = getNumPatternX() >= 3 ? 2 : 0; } } else if(isFluid() || isFluidContainer()) { int color = Otc::FluidTransparent; @@ -156,12 +152,12 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) break; } - xPattern = (color % 4) % getNumPatternsX(); - yPattern = (color / 4) % getNumPatternsY(); + xPattern = (color % 4) % getNumPatternX(); + yPattern = (color / 4) % getNumPatternY(); } else if(isGround() || isOnBottom()) { - xPattern = m_position.x % getNumPatternsX(); - yPattern = m_position.y % getNumPatternsY(); - zPattern = m_position.z % getNumPatternsZ(); + xPattern = m_position.x % getNumPatternX(); + yPattern = m_position.y % getNumPatternY(); + zPattern = m_position.z % getNumPatternZ(); } bool useShader = g_painter->hasShaders() && m_shaderProgram; @@ -172,7 +168,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) g_painter->setShaderProgram(m_shaderProgram); } - m_type->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase); + m_datType->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase); if(useShader) g_painter->resetShaderProgram(); @@ -180,16 +176,10 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) void Item::setId(uint32 id) { - if(id < g_thingsType.getFirstItemId() || id > g_thingsType.getMaxItemid()) { - g_logger.traceError(stdext::format("invalid item id %d", id)); - return; - } + m_datType = g_things.getDatType(id, DatItemCategory); m_id = id; - m_type = g_thingsType.getThingType(m_id, ThingsType::Item); } - - bool Item::unserializeAttr(FileStreamPtr fin) { uint8 attrType; diff --git a/src/otclient/core/item.h b/src/otclient/core/item.h index 5d1fb0f1..103e0a87 100644 --- a/src/otclient/core/item.h +++ b/src/otclient/core/item.h @@ -100,7 +100,7 @@ public: bool unserializeItemNode(FileStreamPtr fin, uint8) { return unserializeAttr(fin); } void readAttr(AttrTypes_t attrType, FileStreamPtr fin); - bool isMovable() { return false; } + bool isMoveable() { return false; } private: uint16 m_id; diff --git a/src/otclient/core/itemloader.h b/src/otclient/core/itemloader.h deleted file mode 100644 index e6041716..00000000 --- a/src/otclient/core/itemloader.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTBLOADER_H -#define OTBLOADER_H - -#include "declarations.h" - -enum ItemGroup { - IsGround, - IsContainer, - IsWeapon, - IsAmmunition, - IsArmor, - IsCharges, - IsTeleport, - IsMagicField, - IsWritable, - IsKey, - IsSplash, - IsFluid, - IsDoor, - InvalidGroup -}; - -enum ItemAttrib { - First = 0x10, - ServerId = First, - ClientId, - Name, /* deprecated */ - Desc, /*deprecated*/ - Speed, - Slot, /*deprecated*/ - MaxItems, /*deprecated*/ - Weight, /*deprecated*/ - Weapon, /*deprecated*/ - Amu, /*deprecated*/ - Armor, /*deprecated*/ - MagLevel, /*deprecated*/ - MagicField, /*deprecated*/ - Writable, /*deprecated*/ - RotateTo, /*deprecated*/ - Decay, /*deprecated*/ - SpriteHash, - MinimapColor, - Attr07, - Attr08, - Light, - - // 1-byte aligned - Decay2, /*deprecated*/ - Weapon2, /*deprecated*/ - Amu2, /*deprecated*/ - Armor2, /*deprecated*/ - Writable2, /*deprecated*/ - Light2, - TopOrder, - Wrtiable3 /*deprecated*/ -}; - -struct ItemData { - uint16 id; - uint16 clientId; - std::string name, description; - int containerSize; - ItemGroup group; - double weight; - - // xml stuff. - bool isDepot; - bool isBed; - uint32 maxTextLength; - uint32 charges; -}; - -class ItemLoader -{ -public: - uint32 dwMajorVersion; - uint32 dwMinorVersion; - uint32 dwBuildNumber; - - ItemLoader() : m_otbLoaded(false), m_xmlLoaded(false) { } - ~ItemLoader(); - - bool loadOtb(const std::string &name); - bool loadXML(const std::string &name); - - bool isLoaded() { return m_otbLoaded && m_xmlLoaded; } - ItemDataPtr getType(uint16 id) const; - void addType(uint16 id, ItemDataPtr type); - -private: - ItemDataList m_items; - bool m_otbLoaded, m_xmlLoaded; -}; - -extern ItemLoader g_itemLoader; - -#endif diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index 842f12aa..26ad6c3d 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -27,7 +27,6 @@ #include "item.h" #include "missile.h" #include "statictext.h" -#include "itemloader.h" #include #include "mapview.h" @@ -36,6 +35,11 @@ Map g_map; +void Map::terminate() +{ + clean(); +} + void Map::addMapView(const MapViewPtr& mapView) { m_mapViews.push_back(mapView); @@ -54,7 +58,7 @@ void Map::notificateTileUpdateToMapViews(const Position& pos) mapView->onTileUpdate(pos); } -bool Map::loadOTBM(const std::string& fileName) +bool Map::loadOtbm(const std::string& fileName) { FileStreamPtr fin = g_resources.openFile(fileName); if (!fin) { @@ -62,13 +66,13 @@ bool Map::loadOTBM(const std::string& fileName) return false; } - if (!g_itemLoader.isLoaded()) { + if (!g_things.isOtbLoaded() || !g_things.isXmlLoaded()) { g_logger.error(stdext::format("OTB and XML are not loaded yet to load a map.")); return false; } uint32 type = 0; - uint8 root = fin->readNode(root, type); + uint8 root = fin->readFirstNode(type); uint32 headerVersion = fin->getU32(); if (!headerVersion || headerVersion > 3) { @@ -82,16 +86,16 @@ bool Map::loadOTBM(const std::string& fileName) return false; } - if (headerMajorItems > g_itemLoader.dwMajorVersion) { + if (headerMajorItems > g_things.getOtbMajorVersion()) { g_logger.error("This map was saved with different OTB version."); return false; } uint32_t headerMinorItems = fin->getU32(); - if (headerMinorItems > g_itemLoader.dwMinorVersion) + if (headerMinorItems > g_things.getOtbMinorVersion()) g_logger.warning("This map needs an updated OTB."); - uint8 node = fin->readNode(root, type); + uint8 node = fin->readNextNode(root, type); if (type != OTBM_MAP_DATA) { g_logger.error("Could not read data node."); return false; @@ -124,7 +128,7 @@ bool Map::loadOTBM(const std::string& fileName) uint8 nodeMapData; do { - nodeMapData = fin->readNode(node, type); + nodeMapData = fin->readNextNode(node, type); if (type == OTBM_TILE_AREA) { uint16 baseX = fin->getU16(), baseY = fin->getU16(); @@ -132,7 +136,7 @@ bool Map::loadOTBM(const std::string& fileName) uint8 nodeTile; do { - nodeTile = fin->readNode(nodeMapData, type); + nodeTile = fin->readNextNode(nodeMapData, type); if (type == OTBM_TILE || type == OTBM_HOUSETILE) { TilePtr tile = 0; @@ -194,7 +198,7 @@ bool Map::loadOTBM(const std::string& fileName) uint8 nodeItem; do { - nodeItem = fin->readNode(nodeTile, type); + nodeItem = fin->readNextNode(nodeTile, type); if (type == OTBM_ITEM) { ItemPtr item = Item::create(fin->getU16()); @@ -204,8 +208,8 @@ bool Map::loadOTBM(const std::string& fileName) } if (item->unserializeItemNode(fin, nodeItem)) { - if (/* house && */item->isMovable()) { - g_logger.warning(stdext::format("Movable item found in house: %d at pos %d %d %d", item->getId(), + if (/* house && */item->isMoveable()) { + g_logger.warning(stdext::format("Moveable item found in house: %d at pos %d %d %d", item->getId(), px, py, pz)); item = 0; } else if (tile) { @@ -242,7 +246,7 @@ bool Map::loadOTBM(const std::string& fileName) } else if (type == OTBM_TOWNS) { uint8 nodeTown; do { - nodeTown = fin->readNode(nodeMapData, type); + nodeTown = fin->readNextNode(nodeMapData, type); if (type == OTBM_TOWN) { uint32 townId = fin->getU32(); @@ -257,7 +261,7 @@ bool Map::loadOTBM(const std::string& fileName) } else if (type == OTBM_WAYPOINTS && headerVersion > 1) { uint8 nodeWaypoint; do { - nodeWaypoint = fin->readNode(nodeMapData, type); + nodeWaypoint = fin->readNextNode(nodeMapData, type); if (type == OTBM_WAYPOINT) { std::string name = fin->getString(); @@ -274,7 +278,7 @@ bool Map::loadOTBM(const std::string& fileName) return true; } -bool Map::loadOTCM(const std::string& fileName) +bool Map::loadOtcm(const std::string& fileName) { if(!g_resources.fileExists(fileName)) { g_logger.error(stdext::format("Unable to load map '%s'", fileName)); @@ -305,7 +309,7 @@ bool Map::loadOTCM(const std::string& fileName) return true; } -void Map::saveOTCM(const std::string& fileName) +void Map::saveOtcm(const std::string& fileName) { std::stringstream out; diff --git a/src/otclient/core/map.h b/src/otclient/core/map.h index 86dad479..d7adccee 100644 --- a/src/otclient/core/map.h +++ b/src/otclient/core/map.h @@ -78,15 +78,17 @@ enum OTBM_NodeTypes_t class Map { public: + void terminate(); + void addMapView(const MapViewPtr& mapView); void removeMapView(const MapViewPtr& mapView); void notificateTileUpdateToMapViews(const Position& pos); - bool loadOTCM(const std::string& fileName); - void saveOTCM(const std::string& fileName); + bool loadOtcm(const std::string& fileName); + void saveOtcm(const std::string& fileName); - bool loadOTBM(const std::string& fileName); - //void saveOTBM(const std::string& fileName); + bool loadOtbm(const std::string& fileName); + //void saveOtbm(const std::string& fileName); void clean(); void cleanDynamicThings(); diff --git a/src/otclient/core/missile.cpp b/src/otclient/core/missile.cpp index e18169fe..d2a0e424 100644 --- a/src/otclient/core/missile.cpp +++ b/src/otclient/core/missile.cpp @@ -21,7 +21,7 @@ */ #include "missile.h" -#include "thingstype.h" +#include "thingtypemanager.h" #include "map.h" #include "tile.h" #include @@ -63,7 +63,7 @@ void Missile::draw(const Point& dest, float scaleFactor, bool animate) } float fraction = m_animationTimer.ticksElapsed() / m_duration; - m_type->draw(dest + m_delta * fraction * scaleFactor, scaleFactor, 0, xPattern, yPattern, 0, 0); + m_datType->draw(dest + m_delta * fraction * scaleFactor, scaleFactor, 0, xPattern, yPattern, 0, 0); } void Missile::setPath(const Position& fromPosition, const Position& toPosition) @@ -84,5 +84,5 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition) void Missile::setId(uint32 id) { m_id = id; - m_type = g_thingsType.getThingType(m_id, ThingsType::Missile); + m_datType = g_things.getDatType(m_id, DatMissileCategory); } diff --git a/src/otclient/core/outfit.cpp b/src/otclient/core/outfit.cpp index 517ce78d..807de33e 100644 --- a/src/otclient/core/outfit.cpp +++ b/src/otclient/core/outfit.cpp @@ -24,7 +24,7 @@ Outfit::Outfit() { - m_category = ThingsType::Creature; + m_category = DatCreatureCategory; m_id = 1; resetClothes(); } diff --git a/src/otclient/core/outfit.h b/src/otclient/core/outfit.h index 3d8af552..797e1248 100644 --- a/src/otclient/core/outfit.h +++ b/src/otclient/core/outfit.h @@ -24,7 +24,7 @@ #define OUTFIT_H #include -#include +#include class Outfit { @@ -44,7 +44,7 @@ public: void setLegs(int legs) { m_legs = legs; m_legsColor = getColor(legs); } void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); } void setAddons(int addons) { m_addons = addons; } - void setCategory(ThingsType::Categories category) { m_category = category; } + void setCategory(DatCategory category) { m_category = category; } void resetClothes(); @@ -54,7 +54,7 @@ public: int getLegs() const { return m_legs; } int getFeet() const { return m_feet; } int getAddons() const { return m_addons; } - ThingsType::Categories getCategory() const { return m_category; } + DatCategory getCategory() const { return m_category; } Color getHeadColor() const { return m_headColor; } Color getBodyColor() const { return m_bodyColor; } @@ -62,7 +62,7 @@ public: Color getFeetColor() const { return m_feetColor; } private: - ThingsType::Categories m_category; + DatCategory m_category; int m_id, m_head, m_body, m_legs, m_feet, m_addons; Color m_headColor, m_bodyColor, m_legsColor, m_feetColor; }; diff --git a/src/otclient/core/spritemanager.cpp b/src/otclient/core/spritemanager.cpp index 3c4c15d4..eb98d373 100644 --- a/src/otclient/core/spritemanager.cpp +++ b/src/otclient/core/spritemanager.cpp @@ -33,7 +33,12 @@ SpriteManager::SpriteManager() m_signature = 0; } -bool SpriteManager::load(const std::string& file) +void SpriteManager::termiante() +{ + unload(); +} + +bool SpriteManager::loadSpr(const std::string& file) { try { m_spritesFile = g_resources.openFile(file); @@ -61,6 +66,11 @@ void SpriteManager::unload() ImagePtr SpriteManager::getSpriteImage(int id) { + enum { + SPRITE_SIZE = 32, + SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4 + }; + if(id == 0) return nullptr; @@ -81,11 +91,6 @@ ImagePtr SpriteManager::getSpriteImage(int id) uint16 pixelDataSize = m_spritesFile->getU16(); - enum { - SPRITE_SIZE = 32, - SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4 - }; - ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE))); uint8 *pixels = image->getPixelData(); diff --git a/src/otclient/core/spritemanager.h b/src/otclient/core/spritemanager.h index d82a44c7..b49582e2 100644 --- a/src/otclient/core/spritemanager.h +++ b/src/otclient/core/spritemanager.h @@ -31,7 +31,9 @@ class SpriteManager public: SpriteManager(); - bool load(const std::string& file); + void termiante(); + + bool loadSpr(const std::string& file); void unload(); uint32 getSignature() { return m_signature; } diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index 56fe81a7..adb96778 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -22,7 +22,7 @@ #include "thing.h" #include "spritemanager.h" -#include "thingstype.h" +#include "thingtypemanager.h" #include #include "map.h" #include "tile.h" @@ -30,7 +30,8 @@ Thing::Thing() { - m_type = g_thingsType.getEmptyThingType(); + m_datType = g_things.getNullDatType(); + m_otbType = g_things.getNullOtbType(); } int Thing::getStackPriority() diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index d7022cc7..f2ab6aea 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -24,7 +24,8 @@ #define THING_H #include "declarations.h" -#include "thingstype.h" +#include "thingtypedat.h" +#include "thingtypeotb.h" #include struct Light @@ -75,51 +76,67 @@ public: virtual bool isAnimatedText() { return false; } virtual bool isStaticText() { return false; } - // type related - bool isGround() { return m_type->getProperty(ThingType::IsGround); } - bool isFullGround() { return m_type->getProperty(ThingType::IsFullGround); } - bool isTranslucent() { return m_type->getProperty(ThingType::IsTranslucent); } - bool isGroundBorder() { return m_type->getProperty(ThingType::IsGroundBorder); } - bool isOnBottom() { return m_type->getProperty(ThingType::IsOnBottom); } - bool isOnTop() { return m_type->getProperty(ThingType::IsOnTop); } - bool isDontHide() { return m_type->getProperty(ThingType::DontHide); } - bool isContainer() { return m_type->getProperty(ThingType::IsContainer); } - bool isForceUse() { return m_type->getProperty(ThingType::IsForceUse); } - bool isMultiUse() { return m_type->getProperty(ThingType::IsMultiUse); } - bool isRotateable() { return m_type->getProperty(ThingType::IsRotateable); } - bool isNotMoveable() { return m_type->getProperty(ThingType::IsNotMovable); } - bool isNotWalkable() { return m_type->getProperty(ThingType::NotWalkable); } - bool isPickupable() { return m_type->getProperty(ThingType::IsPickupable); } - bool isNotPathable() { return m_type->getProperty(ThingType::NotPathable); } - bool isIgnoreLook() { return m_type->getProperty(ThingType::IgnoreLook); } - bool isHangable() { return m_type->getProperty(ThingType::IsHangable); } - bool isHookSouth() { return m_type->getProperty(ThingType::HookSouth); } - bool isHookEast() { return m_type->getProperty(ThingType::HookEast); } - bool isStackable() { return m_type->getProperty(ThingType::IsStackable); } - bool isAnimateAlways() { return m_type->getProperty(ThingType::AnimateAlways); } - bool isLyingCorpse() { return m_type->getProperty(ThingType::IsLyingCorpse); } - bool blocksProjectile() { return m_type->getProperty(ThingType::BlockProjectile); } - bool isFluid() { return m_type->getProperty(ThingType::IsFluid); } - bool isFluidContainer() { return m_type->getProperty(ThingType::IsFluidContainer); } - Size getDimension() { return Size(m_type->getDimension(ThingType::Width), m_type->getDimension(ThingType::Height)); } - int getDimensionWidth() { return m_type->getDimension(ThingType::Width); } - int getDimensionHeight() { return m_type->getDimension(ThingType::Height); } - int getExactSize() { return m_type->getDimension(ThingType::ExactSize); } - Point getDisplacement() { return Point(m_type->getParameter(ThingType::DisplacementX), m_type->getParameter(ThingType::DisplacementY)); } - int getNumPatternsX() { return m_type->getDimension(ThingType::PatternX); } - int getNumPatternsY() { return m_type->getDimension(ThingType::PatternY); } - int getNumPatternsZ() { return m_type->getDimension(ThingType::PatternZ); } - int getDisplacementX() { return m_type->getParameter(ThingType::DisplacementX); } - int getDisplacementY() { return m_type->getParameter(ThingType::DisplacementY); } - int getLayers() { return m_type->getDimension(ThingType::Layers); } - int getAnimationPhases() { return m_type->getDimension(ThingType::AnimationPhases); } - int getGroundSpeed() { return m_type->getParameter(ThingType::GroundSpeed); } - int getElevation() { return m_type->getParameter(ThingType::Elevation); } - int getMinimapColor() { return m_type->getParameter(ThingType::MiniMapColor); } + // type shortcuts + ThingTypeDatPtr getType() { return m_datType; } + Size getSize() { return m_datType->getSize(); } + int getWidth() { return m_datType->getWidth(); } + int getHeight() { return m_datType->getHeight(); } + Point getDisplacement() { return m_datType->getDisplacement(); } + int getDisplacementX() { return m_datType->getDisplacementX(); } + int getDisplacementY() { return m_datType->getDisplacementY(); } + int getExactSize() { return m_datType->getExactSize(); } + int getLayers() { return m_datType->getLayers(); } + int getNumPatternX() { return m_datType->getNumPatternX(); } + int getNumPatternY() { return m_datType->getNumPatternY(); } + int getNumPatternZ() { return m_datType->getNumPatternZ(); } + int getAnimationPhases() { return m_datType->getAnimationPhases(); } + int getGroundSpeed() { return m_datType->getGroundSpeed(); } + int getMaxTextLength() { return m_datType->getMaxTextLength(); } + int getLightLevel() { return m_datType->getLightLevel(); } + int getLightColor() { return m_datType->getLightColor(); } + int getMinimapColor() { return m_datType->getMinimapColor(); } + int getLensHelp() { return m_datType->getLensHelp(); } + int getClothSlot() { return m_datType->getClothSlot(); } + int getElevation() { return m_datType->getElevation(); } + bool isGround() { return m_datType->isGround(); } + bool isGroundBorder() { return m_datType->isGroundBorder(); } + bool isOnBottom() { return m_datType->isOnBottom(); } + bool isOnTop() { return m_datType->isOnTop(); } + bool isContainer() { return m_datType->isContainer(); } + bool isStackable() { return m_datType->isStackable(); } + bool isForceUse() { return m_datType->isForceUse(); } + bool isMultiUse() { return m_datType->isMultiUse(); } + bool isWritable() { return m_datType->isWritable(); } + bool isWritableOnce() { return m_datType->isWritableOnce(); } + bool isFluidContainer() { return m_datType->isFluidContainer(); } + bool isFluid() { return m_datType->isFluid(); } + bool isNotWalkable() { return m_datType->isNotWalkable(); } + bool isNotMoveable() { return m_datType->isNotMoveable(); } + bool blockProjectile() { return m_datType->blockProjectile(); } + bool isNotPathable() { return m_datType->isNotPathable(); } + bool isPickupable() { return m_datType->isPickupable(); } + bool isHangable() { return m_datType->isHangable(); } + bool isHookSouth() { return m_datType->isHookSouth(); } + bool isHookEast() { return m_datType->isHookEast(); } + bool isRotateable() { return m_datType->isRotateable(); } + bool hasLight() { return m_datType->hasLight(); } + bool isDontHide() { return m_datType->isDontHide(); } + bool isTranslucent() { return m_datType->isTranslucent(); } + bool hasDisplacement() { return m_datType->hasDisplacement(); } + bool hasElevation() { return m_datType->hasElevation(); } + bool isLyingCorpse() { return m_datType->isLyingCorpse(); } + bool isAnimateAlways() { return m_datType->isAnimateAlways(); } + bool hasMiniMapColor() { return m_datType->hasMiniMapColor(); } + bool hasLensHelp() { return m_datType->hasLensHelp(); } + bool isFullGround() { return m_datType->isFullGround(); } + bool isIgnoreLook() { return m_datType->isIgnoreLook(); } + bool isCloth() { return m_datType->isCloth(); } protected: Position m_position; - ThingType *m_type; + ThingTypeDatPtr m_datType; + ThingTypeOtbPtr m_otbType; }; #endif + diff --git a/src/otclient/core/thingstype.cpp b/src/otclient/core/thingstype.cpp deleted file mode 100644 index 86b71ff6..00000000 --- a/src/otclient/core/thingstype.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "thingstype.h" -#include "spritemanager.h" -#include "thing.h" -#include -#include - -ThingsType g_thingsType; -ThingType ThingsType::m_emptyThingType; - -bool ThingsType::load(const std::string& file) -{ - FileStreamPtr fin = g_resources.openFile(file); - if(!fin) { - g_logger.error(stdext::format("unable to open dat file '%s'", file)); - return false; - } - - m_signature = fin->getU32(); - - int numThings[LastCategory]; - for(int i = 0; i < LastCategory; ++i) - numThings[i] = fin->getU16(); - - numThings[Item] -= 99; - - for(int i = 0; i < LastCategory; ++i) { - m_things[i].resize(numThings[i]); - for(int id = 0; id < numThings[i]; ++id) { - m_things[i][id].m_category = i; - if(!parseThingType(fin, m_things[i][id])) { - g_logger.error("corrupt or dat file"); - return false; - } - } - } - - m_loaded = true; - return true; -} - -void ThingsType::unload() -{ - for(int i = 0; i < LastCategory; ++i) - m_things[i].clear(); -} - -bool ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType) -{ - bool done = false; - for(int i=0;igetU8(); - if(property == ThingType::LastPropertyValue) { - done = true; - break; - } - - thingType.m_properties[property] = true; - - if(property == ThingType::IsGround) { - int speed = fin->getU16(); - if(speed == 0) - speed = 100; - thingType.m_parameters[ThingType::GroundSpeed] = speed; - } - else if(property == ThingType::IsWritable || property == ThingType::IsWritableOnce) - thingType.m_parameters[ThingType::MaxTextLenght] = fin->getU16(); - else if(property == ThingType::HasLight) { - thingType.m_parameters[ThingType::LightLevel] = fin->getU16(); - thingType.m_parameters[ThingType::LightColor] = fin->getU16(); - } - else if(property == ThingType::HasDisplacement) { - thingType.m_parameters[ThingType::DisplacementX] = fin->getU16(); - thingType.m_parameters[ThingType::DisplacementY] = fin->getU16(); - } - else if(property == ThingType::HasElevation) - thingType.m_parameters[ThingType::Elevation] = fin->getU16(); - else if(property == ThingType::MiniMap) - thingType.m_parameters[ThingType::MiniMapColor] = fin->getU16(); - else if(property == ThingType::LensHelp) - thingType.m_parameters[ThingType::LensHelpParameter] = fin->getU16(); - else if(property == ThingType::Cloth) - thingType.m_parameters[ThingType::ClothSlot] = fin->getU16(); -#if PROTOCOL<=810 - else if(property == ThingType::IsRune) - thingType.m_properties[ThingType::IsStackable] = true; -#endif - else if(property == ThingType::Market) { - fin->getU16(); // category - fin->getU16(); // trade as - fin->getU16(); // show as - fin->getString(); // name - fin->getU16(); // restrict profession - fin->getU16(); // level - } - } - - if(!done) - return false; - - int totalSprites = 1; - for(int i = 0; i < ThingType::LastDimension; ++i) { - int value; - if(i == ThingType::ExactSize) { - if(thingType.m_dimensions[ThingType::Width] <= 1 && thingType.m_dimensions[ThingType::Height] <= 1) - value = 32; - else - value = std::min((int)fin->getU8(), std::max(thingType.m_dimensions[ThingType::Width] * 32, thingType.m_dimensions[ThingType::Height] * 32)); - } else { - value = fin->getU8(); - if(value == 0) - return false; - totalSprites *= value; - } - - thingType.m_dimensions[i] = value; - } - - if(totalSprites > 4096) - return false; - - thingType.m_spritesIndex.resize(totalSprites); - for(int i = 0; i < totalSprites; i++) - thingType.m_spritesIndex[i] = fin->getU16(); - - thingType.m_textures.resize(thingType.m_dimensions[ThingType::AnimationPhases]); - thingType.m_texturesFramesRects.resize(thingType.m_dimensions[ThingType::AnimationPhases]); - thingType.m_texturesFramesOriginRects.resize(thingType.m_dimensions[ThingType::AnimationPhases]); - thingType.m_texturesFramesOffsets.resize(thingType.m_dimensions[ThingType::AnimationPhases]); - - return true; -} - -ThingType *ThingsType::getThingType(uint16 id, Categories category) -{ - if(id == 0) - return &m_emptyThingType; - - if(category == Item) - id -= 100; - else if(category == Creature || category == Effect || category == Missile) - id -= 1; - - if(id >= m_things[category].size()) - return &m_emptyThingType; - return &m_things[category][id]; -} diff --git a/src/otclient/core/thingtype.cpp b/src/otclient/core/thingtype.cpp deleted file mode 100644 index 397652c8..00000000 --- a/src/otclient/core/thingtype.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "thingtype.h" -#include "thingstype.h" -#include "spritemanager.h" - -#include -#include -#include - -ThingType::ThingType() -{ - m_category = 0; - m_dimensions.fill(0); - m_parameters.fill(0); - m_properties.fill(false); -} - -void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase) -{ - const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. - - int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); - Point textureOffset; - Rect textureRect; - - if(scaleFactor != 1.0f) { - textureRect = m_texturesFramesOriginRects[animationPhase][frameIndex]; - } else { - textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; - textureRect = m_texturesFramesRects[animationPhase][frameIndex]; - } - - Point displacement(m_parameters[DisplacementX], m_parameters[DisplacementY]); - Rect screenRect(dest + (-displacement + textureOffset - Point(m_dimensions[Width] - 1, m_dimensions[Height] - 1) * Otc::TILE_PIXELS) * scaleFactor, - textureRect.size() * scaleFactor); - - g_painter->drawTexturedRect(screenRect, texture, textureRect); -} - -TexturePtr& ThingType::getTexture(int animationPhase) -{ - TexturePtr& animationPhaseTexture = m_textures[animationPhase]; - if(!animationPhaseTexture) { - // we don't need layers in common items, they will be pre-drawn - int textureLayers = 1; - int numLayers = m_dimensions[Layers]; - if(m_category == ThingsType::Creature && m_dimensions[Layers] >= 2) { - // 5 layers: outfit base, red mask, green mask, blue mask, yellow mask - textureLayers = 5; - numLayers = 5; - } - - int indexSize = textureLayers * m_dimensions[PatternX] * m_dimensions[PatternY] * m_dimensions[PatternZ]; - Size textureSize = getBestDimension(m_dimensions[Width], m_dimensions[Height], indexSize); - ImagePtr fullImage = ImagePtr(new Image(textureSize * Otc::TILE_PIXELS)); - - m_texturesFramesRects[animationPhase].resize(indexSize); - m_texturesFramesOriginRects[animationPhase].resize(indexSize); - m_texturesFramesOffsets[animationPhase].resize(indexSize); - - for(int z = 0; z < m_dimensions[PatternZ]; ++z) { - for(int y = 0; y < m_dimensions[PatternY]; ++y) { - for(int x = 0; x < m_dimensions[PatternX]; ++x) { - for(int l = 0; l < numLayers; ++l) { - bool spriteMask = (m_category == ThingsType::Creature && l > 0); - int frameIndex = getTextureIndex(l % textureLayers, x, y, z); - Point framePos = Point(frameIndex % (textureSize.width() / m_dimensions[Width]) * m_dimensions[Width], - frameIndex / (textureSize.width() / m_dimensions[Width]) * m_dimensions[Height]) * Otc::TILE_PIXELS; - - for(int h = 0; h < m_dimensions[Height]; ++h) { - for(int w = 0; w < m_dimensions[Width]; ++w) { - uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y, z, animationPhase); - ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]); - if(spriteImage) { - if(spriteMask) { - static Color maskColors[] = { Color::red, Color::green, Color::blue, Color::yellow }; - spriteImage->overwriteMask(maskColors[l - 1]); - } - Point spritePos = Point(m_dimensions[Width] - w - 1, - m_dimensions[Height] - h - 1) * Otc::TILE_PIXELS; - - fullImage->blit(framePos + spritePos, spriteImage); - } - } - } - - Rect drawRect(framePos + Point(m_dimensions[Width], m_dimensions[Height]) * Otc::TILE_PIXELS - Point(1,1), framePos); - for(int x = framePos.x; x < framePos.x + m_dimensions[Width] * Otc::TILE_PIXELS; ++x) { - for(int y = framePos.y; y < framePos.y + m_dimensions[Height] * Otc::TILE_PIXELS; ++y) { - uint8 *p = fullImage->getPixel(x,y); - if(p[3] != 0x00) { - drawRect.setTop (std::min(y, (int)drawRect.top())); - drawRect.setLeft (std::min(x, (int)drawRect.left())); - drawRect.setBottom(std::max(y, (int)drawRect.bottom())); - drawRect.setRight (std::max(x, (int)drawRect.right())); - } - } - } - - m_texturesFramesRects[animationPhase][frameIndex] = drawRect; - m_texturesFramesOriginRects[animationPhase][frameIndex] = Rect(framePos, Size(m_dimensions[Width], m_dimensions[Height]) * Otc::TILE_PIXELS); - m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos; - } - } - } - } - animationPhaseTexture = TexturePtr(new Texture(fullImage, true)); - animationPhaseTexture->setSmooth(true); - } - return animationPhaseTexture; -} - -Size ThingType::getBestDimension(int w, int h, int count) -{ - const int MAX = 32; - - int k = 1; - while(k < w) - k<<=1; - w = k; - - k = 1; - while(k < h) - k<<=1; - h = k; - - int numSprites = w*h*count; - assert(numSprites <= MAX*MAX); - assert(w <= MAX); - assert(h <= MAX); - - Size bestDimension = Size(MAX, MAX); - for(int i=w;i<=MAX;i<<=1) { - for(int j=h;j<=MAX;j<<=1) { - Size candidateDimension = Size(i, j); - if(candidateDimension.area() < numSprites) - continue; - if((candidateDimension.area() < bestDimension.area()) || - (candidateDimension.area() == bestDimension.area() && candidateDimension.width() + candidateDimension.height() < bestDimension.width() + bestDimension.height())) - bestDimension = candidateDimension; - } - } - - return bestDimension; -} diff --git a/src/otclient/core/thingtype.h b/src/otclient/core/thingtype.h deleted file mode 100644 index f8305010..00000000 --- a/src/otclient/core/thingtype.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef THINGATTRIBUTES_H -#define THINGATTRIBUTES_H - -#include "declarations.h" -#include -#include - -class ThingType -{ -public: - enum Dimension { - Width = 0, - Height, - ExactSize, - Layers, - PatternX, - PatternY, - PatternZ, - AnimationPhases, - LastDimension - }; - - enum Property { - IsGround = 0, - IsGroundBorder, - IsOnBottom, - IsOnTop, - IsContainer, - IsStackable, - IsForceUse, - IsMultiUse, -#if PROTOCOL<=854 - IsRune, -#endif - IsWritable, - IsWritableOnce, - IsFluidContainer, - IsFluid, - NotWalkable, - IsNotMovable, - BlockProjectile, - NotPathable, - IsPickupable, - IsHangable, - HookSouth, - HookEast, - IsRotateable, - HasLight, - DontHide, - IsTranslucent, - HasDisplacement, - HasElevation, - IsLyingCorpse, - AnimateAlways, - MiniMap, - LensHelp, - IsFullGround, - IgnoreLook, - Cloth, - Market, - LastProperty, - LastPropertyValue = 255 - }; - - enum Parameter { - GroundSpeed = 0, - Fluid, - MaxTextLenght, - LightLevel, - LightColor, - MiniMapColor, - LensHelpParameter, - ClothSlot, - DisplacementX, - DisplacementY, - Elevation, - LastParameter - }; - - enum SpriteMask { - RedMask = 1, - GreenMask, - BlueMask, - YellowMask, - LastMask - }; - - ThingType(); - - void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase); - void drawMask(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase, SpriteMask mask); - - TexturePtr& getTexture(int animationPhase); - - bool getProperty(Property property) { return m_properties[property]; } - int getParameter(Parameter param) { return m_parameters[param]; } - int getDimension(Dimension dimension) { return m_dimensions[dimension]; } - -private: - Size getBestDimension(int w, int h, int count); - - uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) { - uint index = ((((((a % m_dimensions[ThingType::AnimationPhases]) - * m_dimensions[ThingType::PatternZ] + z) - * m_dimensions[ThingType::PatternY] + y) - * m_dimensions[ThingType::PatternX] + x) - * m_dimensions[ThingType::Layers] + l) - * m_dimensions[ThingType::Height] + h) - * m_dimensions[ThingType::Width] + w; - assert(index < m_spritesIndex.size()); - return index; - } - - uint getTextureIndex(int l, int x, int y, int z) { - return ((l - * m_dimensions[ThingType::PatternZ] + z) - * m_dimensions[ThingType::PatternY] + y) - * m_dimensions[ThingType::PatternX] + x; - } - - int m_category; - std::array m_dimensions; - std::array m_parameters; - std::array m_properties; - std::vector m_spritesIndex; - - std::vector m_textures; - std::vector > m_texturesFramesRects; - std::vector > m_texturesFramesOriginRects; - std::vector > m_texturesFramesOffsets; - - friend class ThingsType; -}; - -#endif diff --git a/src/otclient/core/thingtypedat.cpp b/src/otclient/core/thingtypedat.cpp new file mode 100644 index 00000000..8d0b78fa --- /dev/null +++ b/src/otclient/core/thingtypedat.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "thingtypedat.h" +#include "spritemanager.h" + +#include +#include +#include +#include +#include + +ThingTypeDat::ThingTypeDat() +{ + m_category = DatInvalidCategory; + m_id = 0; + m_exactSize = 0; + m_layers = 0; + m_numPatternX = 0; + m_numPatternY = 0; + m_numPatternZ = 0; + m_animationPhases = 0; + m_groundSpeed = 0; + m_maxTextLenght = 0; + m_lightLevel = 0; + m_lightColor = 0; + m_miniMapColor = 0; + m_lensHelp = 0; + m_clothSlot = 0; + m_elevation = 0; +} + +void ThingTypeDat::unserialize(uint16 clientId, DatCategory category, const FileStreamPtr& fin) +{ + m_null = false; + m_id = clientId; + m_category = category; + + bool done = false; + for(int i = 0 ; i < DatLastAttrib;++i) { + int property = fin->getU8(); + if(property == DatLastAttrib) { + done = true; + break; + } + + switch(property) { + case DatAttribIsGround: + m_isGround = true; + m_groundSpeed = fin->getU16(); + if(m_groundSpeed == 0) + m_groundSpeed = 100; + break; + case DatAttribIsGroundBorder: + m_isGroundBorder = true; + break; + case DatAttribIsOnBottom: + m_isOnBottom = true; + break; + case DatAttribIsOnTop: + m_isOnTop = true; + break; + case DatAttribIsContainer: + m_isContainer = true; + break; + case DatAttribIsStackable: + m_isStackable = true; + break; + case DatAttribIsForceUse: + m_isForceUse = true; + break; + case DatAttribIsMultiUse: + m_isMultiUse = true; + break; + case DatAttribIsWritable: + m_isWritable = true; + m_maxTextLenght = fin->getU16(); + break; + case DatAttribIsWritableOnce: + m_isWritableOnce = true; + m_maxTextLenght = fin->getU16(); + break; + case DatAttribIsFluidContainer: + m_isFluidContainer = true; + break; + case DatAttribIsFluid: + m_isFluid = true; + break; + case DatAttribIsNotWalkable: + m_isNotWalkable = true; + break; + case DatAttribIsNotMoveable: + m_isNotMoveable = true; + break; + case DatAttribBlockProjectile: + m_blockProjectile = true; + break; + case DatAttribIsNotPathable: + m_isNotPathable = true; + break; + case DatAttribIsPickupable: + m_isPickupable = true; + break; + case DatAttribIsHangable: + m_isHangable = true; + break; + case DatAttribHookSouth: + m_isHookSouth = true; + break; + case DatAttribHookEast: + m_isHookEast = true; + break; + case DatAttribIsRotateable: + m_isRotateable = true; + break; + case DatAttribHasLight: + m_hasLight = true; + m_lightLevel = fin->getU16(); + m_lightColor = fin->getU16(); + break; + case DatAttribDontHide: + m_isDontHide = true; + break; + case DatAttribIsTranslucent: + m_isTranslucent = true; + break; + case DatAttribHasDisplacement: + m_hasDisplacement = true; + m_displacement = Point(fin->getU16(), fin->getU16()); + break; + case DatAttribHasElevation: + m_hasElevation = true; + m_elevation = fin->getU16(); + break; + case DatAttribIsLyingCorpse: + m_isLyingCorpse = true; + break; + case DatAttribAnimateAlways: + m_isAnimateAlways = true; + break; + case DatAttribMiniMapColor: + m_miniMapColor = true; + m_miniMapColor = fin->getU16(); + break; + case DatAttribLensHelp: + m_lensHelp = true; + m_lensHelp = fin->getU16(); + break; + case DatAttribIsFullGround: + m_isFullGround = true; + break; + case DatAttribIgnoreLook: + m_isIgnoreLook = true; + break; + case DatAttribCloth: + m_isCloth = true; + m_clothSlot = fin->getU16(); + break; + case DatAttribMarket: + fin->getU16(); // category + fin->getU16(); // trade as + fin->getU16(); // show as + fin->getString(); // name + fin->getU16(); // restrict profession + fin->getU16(); // level + break; + default: + stdext::throw_exception("corrupt data, invalid type attribute"); + break; + }; + } + + if(!done) + stdext::throw_exception("corrupt data"); + + int totalSprites = 1; + for(int i = 0; i < DatLastDimension; ++i) { + switch(i) { + case DatWidth: + m_size.setWidth(fin->getU8()); + break; + case DatHeight: + m_size.setHeight(fin->getU8()); + break; + case DatExactSize: + if(m_size.width() <= 1 && m_size.height() <= 1) + m_exactSize = 32; + else + m_exactSize = std::min((int)fin->getU8(), std::max(m_size.width() * 32, m_size.height() * 32)); + break; + case DatLayers: + m_layers = fin->getU8(); + break; + case DatPatternX: + m_numPatternX = fin->getU8(); + break; + case DatPatternY: + m_numPatternY = fin->getU8(); + break; + case DatPatternZ: + m_numPatternZ = fin->getU8(); + break; + case DatAnimationPhases: + m_animationPhases = fin->getU8(); + break; + } + } + + totalSprites = m_size.width() * m_size.height() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; + if(totalSprites == 0) + stdext::throw_exception("a thing type has no sprites"); + if(totalSprites > 4096) + stdext::throw_exception("a thing type has more than 4096 sprites"); + + m_spritesIndex.resize(totalSprites); + for(int i = 0; i < totalSprites; i++) + m_spritesIndex[i] = fin->getU16(); + + m_textures.resize(m_animationPhases); + m_texturesFramesRects.resize(m_animationPhases); + m_texturesFramesOriginRects.resize(m_animationPhases); + m_texturesFramesOffsets.resize(m_animationPhases); +} + +void ThingTypeDat::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase) +{ + if(m_null) + return; + + const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. + + int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); + Point textureOffset; + Rect textureRect; + + if(scaleFactor != 1.0f) { + textureRect = m_texturesFramesOriginRects[animationPhase][frameIndex]; + } else { + textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; + textureRect = m_texturesFramesRects[animationPhase][frameIndex]; + } + + Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * 32) * scaleFactor, + textureRect.size() * scaleFactor); + + g_painter->drawTexturedRect(screenRect, texture, textureRect); +} + +const TexturePtr& ThingTypeDat::getTexture(int animationPhase) +{ + TexturePtr& animationPhaseTexture = m_textures[animationPhase]; + if(!animationPhaseTexture) { + // we don't need layers in common items, they will be pre-drawn + int textureLayers = 1; + int numLayers = m_layers; + if(m_category == DatCreatureCategory && numLayers >= 2) { + // 5 layers: outfit base, red mask, green mask, blue mask, yellow mask + textureLayers = 5; + numLayers = 5; + } + + int indexSize = textureLayers * m_numPatternX * m_numPatternY * m_numPatternZ; + Size textureSize = getBestTextureDimension(m_size.width(), m_size.height(), indexSize); + ImagePtr fullImage = ImagePtr(new Image(textureSize * Otc::TILE_PIXELS)); + + m_texturesFramesRects[animationPhase].resize(indexSize); + m_texturesFramesOriginRects[animationPhase].resize(indexSize); + m_texturesFramesOffsets[animationPhase].resize(indexSize); + + for(int z = 0; z < m_numPatternZ; ++z) { + for(int y = 0; y < m_numPatternY; ++y) { + for(int x = 0; x < m_numPatternX; ++x) { + for(int l = 0; l < numLayers; ++l) { + bool spriteMask = (m_category == DatCreatureCategory && l > 0); + int frameIndex = getTextureIndex(l % textureLayers, x, y, z); + Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(), + frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * Otc::TILE_PIXELS; + + for(int h = 0; h < m_size.height(); ++h) { + for(int w = 0; w < m_size.width(); ++w) { + uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y, z, animationPhase); + ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]); + if(spriteImage) { + if(spriteMask) { + static Color maskColors[] = { Color::red, Color::green, Color::blue, Color::yellow }; + spriteImage->overwriteMask(maskColors[l - 1]); + } + Point spritePos = Point(m_size.width() - w - 1, + m_size.height() - h - 1) * Otc::TILE_PIXELS; + + fullImage->blit(framePos + spritePos, spriteImage); + } + } + } + + Rect drawRect(framePos + Point(m_size.width(), m_size.height()) * Otc::TILE_PIXELS - Point(1,1), framePos); + for(int x = framePos.x; x < framePos.x + m_size.width() * Otc::TILE_PIXELS; ++x) { + for(int y = framePos.y; y < framePos.y + m_size.height() * Otc::TILE_PIXELS; ++y) { + uint8 *p = fullImage->getPixel(x,y); + if(p[3] != 0x00) { + drawRect.setTop (std::min(y, (int)drawRect.top())); + drawRect.setLeft (std::min(x, (int)drawRect.left())); + drawRect.setBottom(std::max(y, (int)drawRect.bottom())); + drawRect.setRight (std::max(x, (int)drawRect.right())); + } + } + } + + m_texturesFramesRects[animationPhase][frameIndex] = drawRect; + m_texturesFramesOriginRects[animationPhase][frameIndex] = Rect(framePos, Size(m_size.width(), m_size.height()) * Otc::TILE_PIXELS); + m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos; + } + } + } + } + animationPhaseTexture = TexturePtr(new Texture(fullImage, true)); + animationPhaseTexture->setSmooth(true); + } + return animationPhaseTexture; +} + +Size ThingTypeDat::getBestTextureDimension(int w, int h, int count) +{ + const int MAX = 32; + + int k = 1; + while(k < w) + k<<=1; + w = k; + + k = 1; + while(k < h) + k<<=1; + h = k; + + int numSprites = w*h*count; + assert(numSprites <= MAX*MAX); + assert(w <= MAX); + assert(h <= MAX); + + Size bestDimension = Size(MAX, MAX); + for(int i=w;i<=MAX;i<<=1) { + for(int j=h;j<=MAX;j<<=1) { + Size candidateDimension = Size(i, j); + if(candidateDimension.area() < numSprites) + continue; + if((candidateDimension.area() < bestDimension.area()) || + (candidateDimension.area() == bestDimension.area() && candidateDimension.width() + candidateDimension.height() < bestDimension.width() + bestDimension.height())) + bestDimension = candidateDimension; + } + } + + return bestDimension; +} + +uint ThingTypeDat::getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) { + uint index = + ((((((a % m_animationPhases) + * m_numPatternZ + z) + * m_numPatternY + y) + * m_numPatternX + x) + * m_layers + l) + * m_size.height() + h) + * m_size.width() + w; + assert(index < m_spritesIndex.size()); + return index; +} + +uint ThingTypeDat::getTextureIndex(int l, int x, int y, int z) { + return ((l * m_numPatternZ + z) + * m_numPatternY + y) + * m_numPatternX + x; +} diff --git a/src/otclient/core/thingtypedat.h b/src/otclient/core/thingtypedat.h new file mode 100644 index 00000000..ef61ab11 --- /dev/null +++ b/src/otclient/core/thingtypedat.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef THINGTYPEDAT_H +#define THINGTYPEDAT_H + +#include "declarations.h" +#include +#include +#include +#include +#include + +enum DatCategory { + DatItemCategory = 0, + DatCreatureCategory, + DatEffectCategory, + DatMissileCategory, + DatLastCategory, + DatInvalidCategory = DatLastCategory +}; + +enum DatSpriteMask { + DatRedMask = 1, + DatGreenMask, + DatBlueMask, + DatYellowMask, + DatLastMask +}; + +enum DatAttrib { + DatAttribIsGround = 0, + DatAttribIsGroundBorder, + DatAttribIsOnBottom, + DatAttribIsOnTop, + DatAttribIsContainer, + DatAttribIsStackable, + DatAttribIsForceUse, + DatAttribIsMultiUse, + DatAttribIsWritable, + DatAttribIsWritableOnce, + DatAttribIsFluidContainer, + DatAttribIsFluid, + DatAttribIsNotWalkable, + DatAttribIsNotMoveable, + DatAttribBlockProjectile, + DatAttribIsNotPathable, + DatAttribIsPickupable, + DatAttribIsHangable, + DatAttribHookSouth, + DatAttribHookEast, + DatAttribIsRotateable, + DatAttribHasLight, + DatAttribDontHide, + DatAttribIsTranslucent, + DatAttribHasDisplacement, + DatAttribHasElevation, + DatAttribIsLyingCorpse, + DatAttribAnimateAlways, + DatAttribMiniMapColor, + DatAttribLensHelp, + DatAttribIsFullGround, + DatAttribIgnoreLook, + DatAttribCloth, + DatAttribMarket, + DatLastAttrib = 255 +}; + +enum DatDimension { + DatWidth = 0, + DatHeight, + DatExactSize, + DatLayers, + DatPatternX, + DatPatternY, + DatPatternZ, + DatAnimationPhases, + DatLastDimension +}; + +class ThingTypeDat : public LuaObject +{ +public: + ThingTypeDat(); + + void unserialize(uint16 clientId, DatCategory category, const FileStreamPtr& fin); + + void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase); + + uint16 getId() { return m_id; } + DatCategory getCategory() { return m_category; } + bool isNull() { return m_null; } + + Size getSize() { return m_size; } + int getWidth() { return m_size.width(); } + int getHeight() { return m_size.height(); } + Point getDisplacement() { return m_displacement; } + int getDisplacementX() { return m_displacement.x; } + int getDisplacementY() { return m_displacement.y; } + int getExactSize() { return m_exactSize; } + int getLayers() { return m_layers; } + int getNumPatternX() { return m_numPatternX; } + int getNumPatternY() { return m_numPatternY; } + int getNumPatternZ() { return m_numPatternZ; } + int getAnimationPhases() { return m_animationPhases; } + int getGroundSpeed() { return m_groundSpeed; } + int getMaxTextLength() { return m_maxTextLenght; } + int getLightLevel() { return m_lightLevel; } + int getLightColor() { return m_lightColor; } + int getMinimapColor() { return m_miniMapColor; } + int getLensHelp() { return m_lensHelp; } + int getClothSlot() { return m_clothSlot; } + int getElevation() { return m_elevation; } + bool isGround() { return m_isGround; } + bool isGroundBorder() { return m_isGroundBorder; } + bool isOnBottom() { return m_isOnBottom; } + bool isOnTop() { return m_isOnTop; } + bool isContainer() { return m_isContainer; } + bool isStackable() { return m_isStackable; } + bool isForceUse() { return m_isForceUse; } + bool isMultiUse() { return m_isMultiUse; } + bool isWritable() { return m_isWritable; } + bool isWritableOnce() { return m_isWritableOnce; } + bool isFluidContainer() { return m_isFluidContainer; } + bool isFluid() { return m_isFluid; } + bool isNotWalkable() { return m_isNotWalkable; } + bool isNotMoveable() { return m_isNotMoveable; } + bool blockProjectile() { return m_blockProjectile; } + bool isNotPathable() { return m_isNotPathable; } + bool isPickupable() { return m_isPickupable; } + bool isHangable() { return m_isHangable; } + bool isHookSouth() { return m_isHookSouth; } + bool isHookEast() { return m_isHookEast; } + bool isRotateable() { return m_isRotateable; } + bool hasLight() { return m_hasLight; } + bool isDontHide() { return m_isDontHide; } + bool isTranslucent() { return m_isTranslucent; } + bool hasDisplacement() { return m_hasDisplacement; } + bool hasElevation() { return m_hasElevation; } + bool isLyingCorpse() { return m_isLyingCorpse; } + bool isAnimateAlways() { return m_isAnimateAlways; } + bool hasMiniMapColor() { return m_hasMiniMapColor; } + bool hasLensHelp() { return m_hasLensHelp; } + bool isFullGround() { return m_isFullGround; } + bool isIgnoreLook() { return m_isIgnoreLook; } + bool isCloth() { return m_isCloth; } + +private: + const TexturePtr& getTexture(int animationPhase); + Size getBestTextureDimension(int w, int h, int count); + 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); + + DatCategory m_category; + uint16 m_id; + Boolean m_null; + + std::vector m_spritesIndex; + std::vector m_textures; + std::vector> m_texturesFramesRects; + std::vector> m_texturesFramesOriginRects; + std::vector> m_texturesFramesOffsets; + + // dat stuff + Size m_size; + Point m_displacement; + int m_exactSize; + int m_layers; + int m_numPatternX; + int m_numPatternY; + int m_numPatternZ; + int m_animationPhases; + int m_groundSpeed; + int m_maxTextLenght; + int m_lightLevel; + int m_lightColor; + int m_miniMapColor; + int m_lensHelp; + int m_clothSlot; + int m_elevation; + Boolean m_isGround; + Boolean m_isGroundBorder; + Boolean m_isOnBottom; + Boolean m_isOnTop; + Boolean m_isContainer; + Boolean m_isStackable; + Boolean m_isForceUse; + Boolean m_isMultiUse; + Boolean m_isWritable; + Boolean m_isWritableOnce; + Boolean m_isFluidContainer; + Boolean m_isFluid; + Boolean m_isNotWalkable; + Boolean m_isNotMoveable; + Boolean m_blockProjectile; + Boolean m_isNotPathable; + Boolean m_isPickupable; + Boolean m_isHangable; + Boolean m_isHookSouth; + Boolean m_isHookEast; + Boolean m_isRotateable; + Boolean m_hasLight; + Boolean m_isDontHide; + Boolean m_isTranslucent; + Boolean m_hasDisplacement; + Boolean m_hasElevation; + Boolean m_isLyingCorpse; + Boolean m_isAnimateAlways; + Boolean m_hasMiniMapColor; + Boolean m_hasLensHelp; + Boolean m_isFullGround; + Boolean m_isIgnoreLook; + Boolean m_isCloth; +}; + +#endif diff --git a/src/otclient/core/thingtypemanager.cpp b/src/otclient/core/thingtypemanager.cpp new file mode 100644 index 00000000..8246cf01 --- /dev/null +++ b/src/otclient/core/thingtypemanager.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "thingtypemanager.h" +#include "spritemanager.h" +#include "thing.h" +#include "thingtypedat.h" +#include "thingtypeotb.h" + +#include +#include + +#define TIXML_USE_STL // use STL strings instead. +#include + +ThingTypeManager g_things; + +void ThingTypeManager::init() +{ + m_nullDatType = ThingTypeDatPtr(new ThingTypeDat); + m_nullOtbType = ThingTypeOtbPtr(new ThingTypeOtb); + m_otbVersion = 0; + m_datSignature = 0; + m_otbVersion = 0; + m_otbMinorVersion = 0; + m_otbMajorVersion = 0; + m_datSignature = 0; + m_datLoaded = false; + m_xmlLoaded = false; + m_otbLoaded = false; +} + +void ThingTypeManager::terminate() +{ + for(int i = 0; i < DatLastCategory; ++i) + m_datTypes[i].clear(); + m_otbTypes.clear(); + m_nullDatType = nullptr; + m_nullOtbType = nullptr; +} + +bool ThingTypeManager::loadDat(const std::string& file) +{ + try { + FileStreamPtr fin = g_resources.openFile(file); + if(!fin) + stdext::throw_exception("unable to open file"); + + m_datSignature = fin->getU32(); + + int numThings[DatLastCategory]; + for(int category = 0; category < DatLastCategory; ++category) { + int count = fin->getU16() + 1; + m_datTypes[category].resize(count, m_nullDatType); + } + + for(int category = 0; category < DatLastCategory; ++category) { + uint16 firstId = 1; + if(category == DatItemCategory) + firstId = 100; + for(uint16 id = firstId; id < m_datTypes[category].size(); ++id) { + ThingTypeDatPtr type(new ThingTypeDat); + type->unserialize(id, (DatCategory)category, fin); + m_datTypes[category][id] = type; + } + } + + m_datLoaded = true; + return true; + } catch(stdext::exception& e) { + g_logger.error(stdext::format("Failed to read dat '%s': %s'", file, e.what())); + return false; + } +} + +bool ThingTypeManager::loadOtb(const std::string& file) +{ + try { + FileStreamPtr fin = g_resources.openFile(file); + if (!fin) + stdext::throw_exception("unable to open file"); + + m_otbVersion = fin->getU32(); + + uint32 type = 0; + uint8 node = fin->readFirstNode(type); + + fin->getU32(); // flags + + uint8 version = fin->getU8(); + if(fin->getU8() == 0x01) { // version + fin->getU8(); // length + m_otbMajorVersion = fin->getU32(); + m_otbMinorVersion = fin->getU32(); + fin->getU32(); // build number + } + + while((node = fin->readNextNode(node, type))) { + ThingTypeOtbPtr otbType(new ThingTypeOtb); + otbType->unserialize((OtbCategory)type, fin); + addOtbType(otbType); + } + + m_otbLoaded = true; + return true; + } catch(stdext::exception& e) { + g_logger.error(stdext::format("failed to load otb '%s': %s", file, e.what())); + return false; + } +} + +bool ThingTypeManager::loadXml(const std::string& file) +{ + /* + TiXmlDocument doc(name.c_str()); + if (!doc.LoadFile()) { + g_logger.error(stdext::format("failed to load xml '%s'", name)); + return false; + } + + TiXmlElement* root = doc.FirstChildElement(); + if (!root) { + g_logger.error("invalid xml root"); + return false; + } + + if (root->ValueTStr() != "items") { + g_logger.error("invalid xml tag name, should be 'items'"); + return false; + } + + for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { + if (element->ValueTStr() != "item") + continue; + + std::string name = element->Attribute("id"); + if (name.empty()) + continue; + + uint16 id = stdext::unsafe_cast(element->Attribute("id")); + uint16 idEx = 0; + if (!id) { + bool found = false; + // fallback into reading fromid and toid + uint16 fromid = stdext::unsafe_cast(element->Attribute("fromid")); + uint16 toid = stdext::unsafe_cast(element->Attribute("toid")); + ThingTypeOtbPtr iType; + for (int __id = fromid; __id < toid; ++__id) { + if (!(iType = getType(__id))) + continue; + + iType->name = name; + idEx = iType->id == fromid ? fromid : toid; + found = true; + } + + if (!found) + continue; + } + + ThingTypeOtbPtr iType = getType(id); + if (!iType) { + iType = ThingTypeOtbPtr(new ItemData); + iType->id = idEx ? idEx : id; + iType->name = name; + addType(iType->id, iType); + } + + iType->name = name; + + for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) { + if (attr->ValueTStr() != "attribute") + continue; + + std::string key = attr->Attribute("key"); + std::string value = attr->Attribute("value"); + if (key == "type") { + if (value == "magicfield") + iType->category = IsMagicField; + else if (value == "key") + iType->category = IsKey; + else if (value == "depot") + iType->isDepot = true; + else if (value == "teleport") + iType->category = IsTeleport; + else if (value == "bed") + iType->isBed = true; + else if (value == "door") + iType->category = IsDoor; + } else if (key == "name") { + iType->name = value; + } else if (key == "description") { + iType->description = value; + } else if (key == "weight") { + iType->weight = stdext::unsafe_cast(stdext::unsafe_cast(value) / 100.f); + } else if (key == "containerSize") { + int containerSize = stdext::unsafe_cast(value); + if (containerSize) + iType->containerSize = containerSize; + iType->category = IsContainer; + } else if (key == "writeable") { + if (!value.empty()) + iType->category = IsWritable; + } else if (key == "maxTextLen") { + iType->maxTextLength = stdext::unsafe_cast(value); + } else if (key == "charges") { + iType->charges = stdext::unsafe_cast(value); + } + } + } + + doc.Clear(); + return true; + */ + return false; +} + +void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType) +{ + uint16 id = otbType->getServerId(); + if(m_otbTypes.size() <= id) + m_otbTypes.resize(id+1, m_nullOtbType); + m_otbTypes[id] = otbType; +} + +ThingTypeDatPtr ThingTypeManager::getDatType(uint16 id, DatCategory category) +{ + if(category >= DatLastCategory || id >= m_datTypes[category].size()) { + g_logger.error(stdext::format("invalid thing type client id %d in category %d", id, category)); + return m_nullDatType; + } + return m_datTypes[category][id]; +} + +ThingTypeOtbPtr ThingTypeManager::getOtbType(uint16 id) +{ + if(id >= m_otbTypes.size()) { + g_logger.error(stdext::format("invalid thing type server id %d", id)); + return m_nullOtbType; + } + return m_otbTypes[id]; +} diff --git a/src/otclient/core/thingtypemanager.h b/src/otclient/core/thingtypemanager.h new file mode 100644 index 00000000..177fff75 --- /dev/null +++ b/src/otclient/core/thingtypemanager.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef THINGTYPEMANAGER_H +#define THINGTYPEMANAGER_H + +#include +#include + +#include "thingtypedat.h" +#include "thingtypeotb.h" + +class ThingTypeManager +{ +public: + void init(); + void terminate(); + + bool loadDat(const std::string& file); + bool loadOtb(const std::string& file); + bool loadXml(const std::string& file); + + void addOtbType(const ThingTypeOtbPtr& otbType); + + ThingTypeDatPtr& getNullDatType() { return m_nullDatType; } + ThingTypeOtbPtr& getNullOtbType() { return m_nullOtbType; } + + ThingTypeDatPtr getDatType(uint16 id, DatCategory category); + ThingTypeOtbPtr getOtbType(uint16 id); + + uint32 getDatSignature() { return m_datSignature; } + uint32 getOtbVersion() { return m_otbVersion; } + uint32 getOtbMajorVersion() { return m_otbMajorVersion; } + uint32 getOtbMinorVersion() { return m_otbMinorVersion; } + + bool isDatLoaded() { return m_datLoaded; } + bool isXmlLoaded() { return m_xmlLoaded; } + bool isOtbLoaded() { return m_otbLoaded; } + + bool isValidDatId(uint16 id, DatCategory category) { return id >= 1 && id < m_datTypes[category].size(); } + bool isValidOtbId(uint16 id) { return id >= 1 && id < m_otbTypes.size(); } + +private: + ThingTypeDatList m_datTypes[DatLastCategory]; + ThingTypeOtbList m_otbTypes; + + ThingTypeDatPtr m_nullDatType; + ThingTypeOtbPtr m_nullOtbType; + + bool m_datLoaded; + bool m_xmlLoaded; + bool m_otbLoaded; + + uint32 m_otbVersion; + uint32 m_otbMinorVersion; + uint32 m_otbMajorVersion; + uint32 m_datSignature; +}; + +extern ThingTypeManager g_things; + +#endif diff --git a/src/otclient/core/thingtypeotb.cpp b/src/otclient/core/thingtypeotb.cpp new file mode 100644 index 00000000..116522aa --- /dev/null +++ b/src/otclient/core/thingtypeotb.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "thingtypeotb.h" + +#include + +ThingTypeOtb::ThingTypeOtb() +{ + m_category = OtbInvalidCateogry; +} + +void ThingTypeOtb::unserialize(OtbCategory category, const FileStreamPtr& fin) +{ + m_null = false; + m_category = category; + fin->getU32(); // skip flags + + bool done = false; + for(int i=0;igetU8(); + + if(attr == 0) { + done = true; + break; + } + + uint16 len = fin->getU16(); + + switch(attr) { + case OtbAttribServerId: + m_serverId = fin->getU16(); + break; + case OtbAttribClientId: + m_clientId = fin->getU16(); + break; + case OtbAttribSpeed: + fin->getU16(); // skip speed + break; + default: + fin->seek(len); // skip attribute + break; + } + } + + if(!done) + stdext::throw_exception("failed to unserialize otb type, corrupt otb?"); +} diff --git a/src/otclient/core/thingtypeotb.h b/src/otclient/core/thingtypeotb.h new file mode 100644 index 00000000..0407c6d2 --- /dev/null +++ b/src/otclient/core/thingtypeotb.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef THINGTYPEOTB_H +#define THINGTYPEOTB_H + +#include +#include + +enum OtbCategory { + OtbGround = 0, + OtbContainer, + OtbWeapon, + OtbAmmunition, + OtbArmor, + OtbCharges, + OtbTeleport, + OtbMagicField, + OtbWritable, + OtbKey, + OtbSplash, + OtbFluid, + OtbDoor, + OtbLastCategory, + OtbInvalidCateogry = OtbLastCategory +}; + +enum OtbAttrib { + OtbAttribFirst = 0x10, + OtbAttribServerId = OtbAttribFirst, + OtbAttribClientId, + OtbAttribName, // deprecated + OtbAttribDesc, // deprecated + OtbAttribSpeed, + OtbAttribSlot, // deprecated + OtbAttribMaxItems, // deprecated + OtbAttribWeight, // deprecated + OtbAttribWeapon, // deprecated + OtbAttribAmu, // deprecated + OtbAttribArmor, // deprecated + OtbAttribMagLevel, // deprecated + OtbAttribMagicField, // deprecated + OtbAttribWritable, // deprecated + OtbAttribRotateTo, // deprecated + OtbAttribDecay, // deprecated + OtbAttribSpriteHash, + OtbAttribMinimapColor, + OtbAttrib07, + OtbAttrib08, + OtbAttribLight, + OtbAttribDecay2, // deprecated + OtbAttribWeapon2, // deprecated + OtbAttribAmu2, // deprecated + OtbAttribArmor2, // deprecated + OtbAttribWritable2, // deprecated + OtbAttribLight2, + OtbAttribTopOrder, + OtbAttribWrtiable3, // deprecated + OtbLastAttrib +}; + +class ThingTypeOtb : public LuaObject +{ +public: + ThingTypeOtb(); + + void unserialize(OtbCategory category, const FileStreamPtr& fin); + + uint16 getServerId() { return m_serverId; } + uint16 getClientId() { return m_clientId; } + OtbCategory getCategory() { return m_category; } + + bool isNull() { return m_null; } + +private: + uint16 m_serverId; + uint16 m_clientId; + OtbCategory m_category; + Boolean m_null; +}; + +#endif + diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index b6472c9b..21ac5d5d 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -22,7 +22,7 @@ #include "tile.h" #include "item.h" -#include "thingstype.h" +#include "thingtypemanager.h" #include "map.h" #include "game.h" #include "localplayer.h" @@ -70,8 +70,8 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); if(thing->isLyingCorpse()) { - redrawPreviousTopW = std::max(thing->getDimensionWidth(), redrawPreviousTopW); - redrawPreviousTopH = std::max(thing->getDimensionHeight(), redrawPreviousTopH); + redrawPreviousTopW = std::max(thing->getWidth(), redrawPreviousTopW); + redrawPreviousTopH = std::max(thing->getHeight(), redrawPreviousTopH); } m_drawElevation += thing->getElevation(); @@ -425,7 +425,7 @@ bool Tile::isFullyOpaque() bool Tile::isLookPossible() { for(const ThingPtr& thing : m_things) { - if(thing->blocksProjectile()) + if(thing->blockProjectile()) return false; } return true; diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 2c28dd61..b23b9bd5 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,16 +47,17 @@ void OTClient::registerLuaFunctions() { - g_lua.registerSingletonClass("g_thingsType"); - g_lua.bindSingletonFunction("g_thingsType", "load", &ThingsType::load, &g_thingsType); - g_lua.bindSingletonFunction("g_thingsType", "isLoaded", &ThingsType::isLoaded, &g_thingsType); - g_lua.bindSingletonFunction("g_thingsType", "getSignature", &ThingsType::getSignature, &g_thingsType); + g_lua.registerSingletonClass("g_things"); + g_lua.bindSingletonFunction("g_things", "loadDat", &ThingTypeManager::loadDat, &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", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things); g_lua.registerSingletonClass("g_sprites"); - g_lua.bindSingletonFunction("g_sprites", "load", &SpriteManager::load, &g_sprites); + g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "isLoaded", &SpriteManager::isLoaded, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "getSignature", &SpriteManager::getSignature, &g_sprites); + g_lua.bindSingletonFunction("g_sprites", "getSprSignature", &SpriteManager::getSignature, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "getSpritesCount", &SpriteManager::getSpritesCount, &g_sprites); g_lua.registerSingletonClass("g_map"); @@ -76,10 +77,10 @@ void OTClient::registerLuaFunctions() g_lua.bindSingletonFunction("g_map", "removeCreatureById", &Map::removeCreatureById, &g_map); g_lua.bindSingletonFunction("g_map", "getSpectators", &Map::getSpectators, &g_map); g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map); - g_lua.bindSingletonFunction("g_map", "loadOTBM", &Map::loadOTBM, &g_map); - //g_lua.bindSingletonFunction("g_map", "saveOTBM", &Map::save, &g_map); - g_lua.bindSingletonFunction("g_map", "loadOTCM", &Map::loadOTCM, &g_map); - g_lua.bindSingletonFunction("g_map", "saveOTCM", &Map::saveOTCM, &g_map); + g_lua.bindSingletonFunction("g_map", "loadOtbm", &Map::loadOtbm, &g_map); + //g_lua.bindSingletonFunction("g_map", "saveOtbm", &Map::saveOtbm, &g_map); + g_lua.bindSingletonFunction("g_map", "loadOtcm", &Map::loadOtcm, &g_map); + g_lua.bindSingletonFunction("g_map", "saveOtcm", &Map::saveOtcm, &g_map); g_lua.registerSingletonClass("g_game"); g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index fdad297a..c455d6e8 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -23,7 +23,7 @@ #include "protocolgame.h" #include -#include +#include #include #include #include @@ -1317,7 +1317,7 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg) int lookType = msg->getU16(); if(lookType != 0) { - outfit.setCategory(ThingsType::Creature); + outfit.setCategory(DatCreatureCategory); int head = msg->getU8(); int body = msg->getU8(); int legs = msg->getU8(); @@ -1334,11 +1334,11 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg) else { int lookTypeEx = msg->getU16(); if(lookTypeEx == 0) { - outfit.setCategory(ThingsType::Effect); + outfit.setCategory(DatEffectCategory); outfit.setId(13); } else { - outfit.setCategory(ThingsType::Item); + outfit.setCategory(DatItemCategory); outfit.setId(lookTypeEx); } } @@ -1492,7 +1492,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id) ItemPtr item = Item::create(id); if(item->getId() == 0) - stdext::throw_exception("unable to create item with invalid id"); + stdext::throw_exception("unable to create item with invalid id 0"); if(item->isStackable() || item->isFluidContainer() || item->isFluid()) item->setCountOrSubType(msg->getU8()); diff --git a/src/otclient/otclient.cpp b/src/otclient/otclient.cpp index 676fd7e9..b69e3425 100644 --- a/src/otclient/otclient.cpp +++ b/src/otclient/otclient.cpp @@ -27,6 +27,7 @@ #include #include #include +#include "core/spritemanager.h" #include OTClient g_otclient; @@ -37,6 +38,7 @@ void OTClient::init(const std::vector& args) registerLuaFunctions(); g_shaders.init(); + g_things.init(); //TODO: restore options /* @@ -77,7 +79,8 @@ void OTClient::init(const std::vector& args) void OTClient::terminate() { + g_map.terminate(); + g_things.terminate(); + g_sprites.termiante(); g_shaders.terminate(); - g_map.clean(); - g_thingsType.unload(); }