changes for otb compability
This commit is contained in:
parent
f3499efe83
commit
96c363d997
|
@ -7,8 +7,8 @@ local function sendLoginPacket(protocol)
|
||||||
msg:addU16(1) -- todo: ClientOs
|
msg:addU16(1) -- todo: ClientOs
|
||||||
msg:addU16(g_game.getClientVersion())
|
msg:addU16(g_game.getClientVersion())
|
||||||
|
|
||||||
msg:addU32(g_thingsType.getSignature())
|
msg:addU32(g_things.getDatSignature())
|
||||||
msg:addU32(g_sprites.getSignature())
|
msg:addU32(g_sprites.getSprSignature())
|
||||||
msg:addU32(0) -- todo: pic signature
|
msg:addU32(0) -- todo: pic signature
|
||||||
|
|
||||||
local paddingBytes = 128
|
local paddingBytes = 128
|
||||||
|
|
|
@ -4,9 +4,9 @@ Module
|
||||||
reloadable: false
|
reloadable: false
|
||||||
|
|
||||||
@onLoad: |
|
@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"))
|
fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat"))
|
||||||
end
|
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"))
|
fatal(tr("Unable to load spr file, please place a valid Tibia spr in modules/game_tibiafiles/Tibia.spr"))
|
||||||
end
|
end
|
||||||
|
|
|
@ -249,28 +249,30 @@ std::string FileStream::getString()
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 FileStream::readNode(uint8 &oldNode, uint32 &type)
|
uint8 FileStream::readFirstNode(uint32& type)
|
||||||
{
|
{
|
||||||
if (!oldNode) {
|
dump << "first";
|
||||||
if ((oldNode = getU8()) == 0xFE) {
|
uint8 node = getU8();
|
||||||
type = getU32();
|
if(node != NODE_START)
|
||||||
return oldNode;
|
stdext::throw_exception("failed to read first node");
|
||||||
} else {
|
type = getU32();
|
||||||
dump << "Failed to read new node.";
|
return node;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(getU8() == 0xFF);
|
uint8 FileStream::readNextNode(uint8 oldNode, uint32& type)
|
||||||
if ((oldNode = getU8()) == 0xFE) {
|
{
|
||||||
type = getU32();
|
dump << "next";
|
||||||
return oldNode;
|
// end of old node
|
||||||
} else {
|
if(getU8() != NODE_END)
|
||||||
dump << "Failed to read node with old type: " << type;
|
stdext::throw_exception("node not ended");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
// next node
|
||||||
|
uint8 node = getU8();
|
||||||
|
if(oldNode != NODE_START)
|
||||||
|
stdext::throw_exception("invalid node start");
|
||||||
|
|
||||||
|
type = getU32();
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileStream::addU8(uint8 v)
|
void FileStream::addU8(uint8 v)
|
||||||
|
|
|
@ -29,6 +29,12 @@ struct PHYSFS_File;
|
||||||
|
|
||||||
class FileStream
|
class FileStream
|
||||||
{
|
{
|
||||||
|
enum {
|
||||||
|
NODE_START = 0xFE,
|
||||||
|
NODE_END = 0xFF,
|
||||||
|
ESCAPE_CHAR = 0xFD,
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FileStream(const std::string& name, PHYSFS_File *fileHandle);
|
FileStream(const std::string& name, PHYSFS_File *fileHandle);
|
||||||
|
|
||||||
|
@ -59,7 +65,9 @@ public:
|
||||||
void addU32(uint8 v);
|
void addU32(uint8 v);
|
||||||
void addU64(uint8 v);
|
void addU64(uint8 v);
|
||||||
|
|
||||||
uint8 readNode(uint8 &oldNode, uint32 &type);
|
uint8 readFirstNode(uint32& type);
|
||||||
|
uint8 readNextNode(uint8 oldNode, uint32& type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
PHYSFS_File *m_fileHandle;
|
PHYSFS_File *m_fileHandle;
|
||||||
|
|
|
@ -48,8 +48,6 @@ SET(otclient_SOURCES ${otclient_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/shadermanager.h
|
${CMAKE_CURRENT_LIST_DIR}/core/shadermanager.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/item.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/item.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/item.h
|
${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.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/localplayer.h
|
${CMAKE_CURRENT_LIST_DIR}/core/localplayer.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/map.cpp
|
${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/statictext.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thing.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/thing.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thing.h
|
${CMAKE_CURRENT_LIST_DIR}/core/thing.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thingstype.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/thingtypemanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thingstype.h
|
${CMAKE_CURRENT_LIST_DIR}/core/thingtypemanager.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thingtype.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/thingtypedat.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thingtype.h
|
${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.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/tile.h
|
${CMAKE_CURRENT_LIST_DIR}/core/tile.h
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace Otc
|
||||||
DatFluidContainer,
|
DatFluidContainer,
|
||||||
DatSplash,
|
DatSplash,
|
||||||
DatBlockWalk,
|
DatBlockWalk,
|
||||||
DatNotMovable,
|
DatNotMoveable,
|
||||||
DatBlockProjectile,
|
DatBlockProjectile,
|
||||||
DatBlockPathFind,
|
DatBlockPathFind,
|
||||||
DatPickupable,
|
DatPickupable,
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "creature.h"
|
#include "creature.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypemanager.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.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)
|
void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction)
|
||||||
{
|
{
|
||||||
// outfit is a real creature
|
// outfit is a real creature
|
||||||
if(m_outfit.getCategory() == ThingsType::Creature) {
|
if(m_outfit.getCategory() == DatCreatureCategory) {
|
||||||
int animationPhase = animateWalk ? m_walkAnimationPhase : 0;
|
int animationPhase = animateWalk ? m_walkAnimationPhase : 0;
|
||||||
|
|
||||||
if(isAnimateAlways() && animateIdle) {
|
if(isAnimateAlways() && animateIdle) {
|
||||||
|
@ -107,26 +107,26 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
||||||
xPattern = direction;
|
xPattern = direction;
|
||||||
|
|
||||||
// yPattern => creature addon
|
// yPattern => creature addon
|
||||||
for(int yPattern = 0; yPattern < getNumPatternsY(); yPattern++) {
|
for(int yPattern = 0; yPattern < getNumPatternY(); yPattern++) {
|
||||||
|
|
||||||
// continue if we dont have this addon
|
// continue if we dont have this addon
|
||||||
if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1))))
|
if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_type->draw(dest, scaleFactor, 0, xPattern, yPattern, 0, animationPhase);
|
m_datType->draw(dest, scaleFactor, 0, xPattern, yPattern, 0, animationPhase);
|
||||||
|
|
||||||
if(getLayers() > 1) {
|
if(getLayers() > 1) {
|
||||||
Color oldColor = g_painter->getColor();
|
Color oldColor = g_painter->getColor();
|
||||||
Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
|
Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
|
||||||
g_painter->setCompositionMode(Painter::CompositionMode_Multiply);
|
g_painter->setCompositionMode(Painter::CompositionMode_Multiply);
|
||||||
g_painter->setColor(m_outfit.getHeadColor());
|
g_painter->setColor(m_outfit.getHeadColor());
|
||||||
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());
|
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());
|
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());
|
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->setColor(oldColor);
|
||||||
g_painter->setCompositionMode(oldComposition);
|
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,
|
// when creature is an effect we cant render the first and last animation phase,
|
||||||
// instead we should loop in the phases between
|
// instead we should loop in the phases between
|
||||||
if(m_outfit.getCategory() == ThingsType::Effect) {
|
if(m_outfit.getCategory() == DatEffectCategory) {
|
||||||
animationPhases = std::max(1, animationPhases-2);
|
animationPhases = std::max(1, animationPhases-2);
|
||||||
animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME;
|
animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME;
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,10 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
||||||
animationPhase = animationPhases-1;
|
animationPhase = animationPhases-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_outfit.getCategory() == ThingsType::Effect)
|
if(m_outfit.getCategory() == DatEffectCategory)
|
||||||
animationPhase = std::min(animationPhase+1, getAnimationPhases());
|
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)
|
void Creature::updateWalkAnimation(int totalPixelsWalked)
|
||||||
{
|
{
|
||||||
// update outfit animation
|
// update outfit animation
|
||||||
if(m_outfit.getCategory() != ThingsType::Creature)
|
if(m_outfit.getCategory() != DatCreatureCategory)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int footAnimPhases = getAnimationPhases() - 1;
|
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_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed.
|
||||||
m_outfit = outfit;
|
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)
|
void Creature::setSkull(uint8 skull)
|
||||||
|
|
|
@ -41,16 +41,13 @@ class Effect;
|
||||||
class Missile;
|
class Missile;
|
||||||
class AnimatedText;
|
class AnimatedText;
|
||||||
class StaticText;
|
class StaticText;
|
||||||
class ThingType;
|
class ThingTypeDat;
|
||||||
class ThingsType;
|
class ThingTypeOtb;
|
||||||
class ItemShader;
|
|
||||||
class ItemData;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<MapView> MapViewPtr;
|
typedef std::shared_ptr<MapView> MapViewPtr;
|
||||||
typedef std::shared_ptr<Tile> TilePtr;
|
typedef std::shared_ptr<Tile> TilePtr;
|
||||||
typedef std::shared_ptr<Thing> ThingPtr;
|
typedef std::shared_ptr<Thing> ThingPtr;
|
||||||
typedef std::shared_ptr<Item> ItemPtr;
|
typedef std::shared_ptr<Item> ItemPtr;
|
||||||
typedef std::shared_ptr<ItemData> ItemDataPtr;
|
|
||||||
typedef std::shared_ptr<Container> ContainerPtr;
|
typedef std::shared_ptr<Container> ContainerPtr;
|
||||||
typedef std::shared_ptr<Creature> CreaturePtr;
|
typedef std::shared_ptr<Creature> CreaturePtr;
|
||||||
typedef std::shared_ptr<Monster> MonsterPtr;
|
typedef std::shared_ptr<Monster> MonsterPtr;
|
||||||
|
@ -61,10 +58,11 @@ typedef std::shared_ptr<Effect> EffectPtr;
|
||||||
typedef std::shared_ptr<Missile> MissilePtr;
|
typedef std::shared_ptr<Missile> MissilePtr;
|
||||||
typedef std::shared_ptr<AnimatedText> AnimatedTextPtr;
|
typedef std::shared_ptr<AnimatedText> AnimatedTextPtr;
|
||||||
typedef std::shared_ptr<StaticText> StaticTextPtr;
|
typedef std::shared_ptr<StaticText> StaticTextPtr;
|
||||||
typedef std::shared_ptr<ItemShader> ItemShaderPtr;
|
typedef std::shared_ptr<ThingTypeDat> ThingTypeDatPtr;
|
||||||
|
typedef std::shared_ptr<ThingTypeOtb> ThingTypeOtbPtr;
|
||||||
|
|
||||||
typedef std::vector<ThingPtr> ThingList;
|
typedef std::vector<ThingPtr> ThingList;
|
||||||
typedef std::vector<ThingType> ThingTypeList;
|
typedef std::vector<ThingTypeDatPtr> ThingTypeDatList;
|
||||||
typedef std::vector<ItemDataPtr> ItemDataList;
|
typedef std::vector<ThingTypeOtbPtr> ThingTypeOtbList;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
int animationPhase = 0;
|
int animationPhase = 0;
|
||||||
if(animate)
|
if(animate)
|
||||||
animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1);
|
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()
|
void Effect::startAnimation()
|
||||||
|
@ -47,5 +47,5 @@ void Effect::startAnimation()
|
||||||
void Effect::setId(uint32 id)
|
void Effect::setId(uint32 id)
|
||||||
{
|
{
|
||||||
m_id = id;
|
m_id = id;
|
||||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Effect);
|
m_datType = g_things.getDatType(m_id, DatEffectCategory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -605,7 +605,7 @@ void Game::use(const ThingPtr& thing)
|
||||||
|
|
||||||
void Game::useInventoryItem(int itemId)
|
void Game::useInventoryItem(int itemId)
|
||||||
{
|
{
|
||||||
if(!canPerformGameAction() || !g_thingsType.isValidItemId(itemId))
|
if(!canPerformGameAction() || !g_things.isValidDatId(itemId, DatItemCategory))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
|
Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypemanager.h"
|
||||||
#include "spritemanager.h"
|
#include "spritemanager.h"
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
@ -42,11 +42,7 @@ Item::Item() : Thing()
|
||||||
ItemPtr Item::create(int id)
|
ItemPtr Item::create(int id)
|
||||||
{
|
{
|
||||||
ItemPtr item = ItemPtr(new Item);
|
ItemPtr item = ItemPtr(new Item);
|
||||||
if(id < g_thingsType.getFirstItemId() || id > g_thingsType.getMaxItemid())
|
item->setId(id);
|
||||||
g_logger.traceError(stdext::format("invalid item id %d", id));
|
|
||||||
else {
|
|
||||||
item->setId(id);
|
|
||||||
}
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +62,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
|
|
||||||
// determine x,y,z patterns
|
// determine x,y,z patterns
|
||||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||||
if(isStackable() && getNumPatternsX() == 4 && getNumPatternsY() == 2) {
|
if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) {
|
||||||
if(m_countOrSubType <= 0) {
|
if(m_countOrSubType <= 0) {
|
||||||
xPattern = 0;
|
xPattern = 0;
|
||||||
yPattern = 0;
|
yPattern = 0;
|
||||||
|
@ -90,9 +86,9 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
const TilePtr& tile = getTile();
|
const TilePtr& tile = getTile();
|
||||||
if(tile) {
|
if(tile) {
|
||||||
if(tile->mustHookSouth())
|
if(tile->mustHookSouth())
|
||||||
xPattern = getNumPatternsX() >= 2 ? 1 : 0;
|
xPattern = getNumPatternX() >= 2 ? 1 : 0;
|
||||||
else if(tile->mustHookEast())
|
else if(tile->mustHookEast())
|
||||||
xPattern = getNumPatternsX() >= 3 ? 2 : 0;
|
xPattern = getNumPatternX() >= 3 ? 2 : 0;
|
||||||
}
|
}
|
||||||
} else if(isFluid() || isFluidContainer()) {
|
} else if(isFluid() || isFluidContainer()) {
|
||||||
int color = Otc::FluidTransparent;
|
int color = Otc::FluidTransparent;
|
||||||
|
@ -156,12 +152,12 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
xPattern = (color % 4) % getNumPatternsX();
|
xPattern = (color % 4) % getNumPatternX();
|
||||||
yPattern = (color / 4) % getNumPatternsY();
|
yPattern = (color / 4) % getNumPatternY();
|
||||||
} else if(isGround() || isOnBottom()) {
|
} else if(isGround() || isOnBottom()) {
|
||||||
xPattern = m_position.x % getNumPatternsX();
|
xPattern = m_position.x % getNumPatternX();
|
||||||
yPattern = m_position.y % getNumPatternsY();
|
yPattern = m_position.y % getNumPatternY();
|
||||||
zPattern = m_position.z % getNumPatternsZ();
|
zPattern = m_position.z % getNumPatternZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useShader = g_painter->hasShaders() && m_shaderProgram;
|
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);
|
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)
|
if(useShader)
|
||||||
g_painter->resetShaderProgram();
|
g_painter->resetShaderProgram();
|
||||||
|
@ -180,16 +176,10 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
|
|
||||||
void Item::setId(uint32 id)
|
void Item::setId(uint32 id)
|
||||||
{
|
{
|
||||||
if(id < g_thingsType.getFirstItemId() || id > g_thingsType.getMaxItemid()) {
|
m_datType = g_things.getDatType(id, DatItemCategory);
|
||||||
g_logger.traceError(stdext::format("invalid item id %d", id));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_id = id;
|
m_id = id;
|
||||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Item::unserializeAttr(FileStreamPtr fin)
|
bool Item::unserializeAttr(FileStreamPtr fin)
|
||||||
{
|
{
|
||||||
uint8 attrType;
|
uint8 attrType;
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
bool unserializeItemNode(FileStreamPtr fin, uint8) { return unserializeAttr(fin); }
|
bool unserializeItemNode(FileStreamPtr fin, uint8) { return unserializeAttr(fin); }
|
||||||
void readAttr(AttrTypes_t attrType, FileStreamPtr fin);
|
void readAttr(AttrTypes_t attrType, FileStreamPtr fin);
|
||||||
|
|
||||||
bool isMovable() { return false; }
|
bool isMoveable() { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 m_id;
|
uint16 m_id;
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "missile.h"
|
#include "missile.h"
|
||||||
#include "statictext.h"
|
#include "statictext.h"
|
||||||
#include "itemloader.h"
|
|
||||||
|
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
#include "mapview.h"
|
#include "mapview.h"
|
||||||
|
@ -36,6 +35,11 @@
|
||||||
|
|
||||||
Map g_map;
|
Map g_map;
|
||||||
|
|
||||||
|
void Map::terminate()
|
||||||
|
{
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
|
||||||
void Map::addMapView(const MapViewPtr& mapView)
|
void Map::addMapView(const MapViewPtr& mapView)
|
||||||
{
|
{
|
||||||
m_mapViews.push_back(mapView);
|
m_mapViews.push_back(mapView);
|
||||||
|
@ -54,7 +58,7 @@ void Map::notificateTileUpdateToMapViews(const Position& pos)
|
||||||
mapView->onTileUpdate(pos);
|
mapView->onTileUpdate(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::loadOTBM(const std::string& fileName)
|
bool Map::loadOtbm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
FileStreamPtr fin = g_resources.openFile(fileName);
|
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||||
if (!fin) {
|
if (!fin) {
|
||||||
|
@ -62,13 +66,13 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
return false;
|
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."));
|
g_logger.error(stdext::format("OTB and XML are not loaded yet to load a map."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 type = 0;
|
uint32 type = 0;
|
||||||
uint8 root = fin->readNode(root, type);
|
uint8 root = fin->readFirstNode(type);
|
||||||
|
|
||||||
uint32 headerVersion = fin->getU32();
|
uint32 headerVersion = fin->getU32();
|
||||||
if (!headerVersion || headerVersion > 3) {
|
if (!headerVersion || headerVersion > 3) {
|
||||||
|
@ -82,16 +86,16 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerMajorItems > g_itemLoader.dwMajorVersion) {
|
if (headerMajorItems > g_things.getOtbMajorVersion()) {
|
||||||
g_logger.error("This map was saved with different OTB version.");
|
g_logger.error("This map was saved with different OTB version.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t headerMinorItems = fin->getU32();
|
uint32_t headerMinorItems = fin->getU32();
|
||||||
if (headerMinorItems > g_itemLoader.dwMinorVersion)
|
if (headerMinorItems > g_things.getOtbMinorVersion())
|
||||||
g_logger.warning("This map needs an updated OTB.");
|
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) {
|
if (type != OTBM_MAP_DATA) {
|
||||||
g_logger.error("Could not read data node.");
|
g_logger.error("Could not read data node.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -124,7 +128,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
|
|
||||||
uint8 nodeMapData;
|
uint8 nodeMapData;
|
||||||
do {
|
do {
|
||||||
nodeMapData = fin->readNode(node, type);
|
nodeMapData = fin->readNextNode(node, type);
|
||||||
|
|
||||||
if (type == OTBM_TILE_AREA) {
|
if (type == OTBM_TILE_AREA) {
|
||||||
uint16 baseX = fin->getU16(), baseY = fin->getU16();
|
uint16 baseX = fin->getU16(), baseY = fin->getU16();
|
||||||
|
@ -132,7 +136,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
|
|
||||||
uint8 nodeTile;
|
uint8 nodeTile;
|
||||||
do {
|
do {
|
||||||
nodeTile = fin->readNode(nodeMapData, type);
|
nodeTile = fin->readNextNode(nodeMapData, type);
|
||||||
|
|
||||||
if (type == OTBM_TILE || type == OTBM_HOUSETILE) {
|
if (type == OTBM_TILE || type == OTBM_HOUSETILE) {
|
||||||
TilePtr tile = 0;
|
TilePtr tile = 0;
|
||||||
|
@ -194,7 +198,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
|
|
||||||
uint8 nodeItem;
|
uint8 nodeItem;
|
||||||
do {
|
do {
|
||||||
nodeItem = fin->readNode(nodeTile, type);
|
nodeItem = fin->readNextNode(nodeTile, type);
|
||||||
|
|
||||||
if (type == OTBM_ITEM) {
|
if (type == OTBM_ITEM) {
|
||||||
ItemPtr item = Item::create(fin->getU16());
|
ItemPtr item = Item::create(fin->getU16());
|
||||||
|
@ -204,8 +208,8 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->unserializeItemNode(fin, nodeItem)) {
|
if (item->unserializeItemNode(fin, nodeItem)) {
|
||||||
if (/* house && */item->isMovable()) {
|
if (/* house && */item->isMoveable()) {
|
||||||
g_logger.warning(stdext::format("Movable item found in house: %d at pos %d %d %d", item->getId(),
|
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %d %d %d", item->getId(),
|
||||||
px, py, pz));
|
px, py, pz));
|
||||||
item = 0;
|
item = 0;
|
||||||
} else if (tile) {
|
} else if (tile) {
|
||||||
|
@ -242,7 +246,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
} else if (type == OTBM_TOWNS) {
|
} else if (type == OTBM_TOWNS) {
|
||||||
uint8 nodeTown;
|
uint8 nodeTown;
|
||||||
do {
|
do {
|
||||||
nodeTown = fin->readNode(nodeMapData, type);
|
nodeTown = fin->readNextNode(nodeMapData, type);
|
||||||
|
|
||||||
if (type == OTBM_TOWN) {
|
if (type == OTBM_TOWN) {
|
||||||
uint32 townId = fin->getU32();
|
uint32 townId = fin->getU32();
|
||||||
|
@ -257,7 +261,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
} else if (type == OTBM_WAYPOINTS && headerVersion > 1) {
|
} else if (type == OTBM_WAYPOINTS && headerVersion > 1) {
|
||||||
uint8 nodeWaypoint;
|
uint8 nodeWaypoint;
|
||||||
do {
|
do {
|
||||||
nodeWaypoint = fin->readNode(nodeMapData, type);
|
nodeWaypoint = fin->readNextNode(nodeMapData, type);
|
||||||
|
|
||||||
if (type == OTBM_WAYPOINT) {
|
if (type == OTBM_WAYPOINT) {
|
||||||
std::string name = fin->getString();
|
std::string name = fin->getString();
|
||||||
|
@ -274,7 +278,7 @@ bool Map::loadOTBM(const std::string& fileName)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::loadOTCM(const std::string& fileName)
|
bool Map::loadOtcm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
if(!g_resources.fileExists(fileName)) {
|
if(!g_resources.fileExists(fileName)) {
|
||||||
g_logger.error(stdext::format("Unable to load map '%s'", 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::saveOTCM(const std::string& fileName)
|
void Map::saveOtcm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
|
|
|
@ -78,15 +78,17 @@ enum OTBM_NodeTypes_t
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void terminate();
|
||||||
|
|
||||||
void addMapView(const MapViewPtr& mapView);
|
void addMapView(const MapViewPtr& mapView);
|
||||||
void removeMapView(const MapViewPtr& mapView);
|
void removeMapView(const MapViewPtr& mapView);
|
||||||
void notificateTileUpdateToMapViews(const Position& pos);
|
void notificateTileUpdateToMapViews(const Position& pos);
|
||||||
|
|
||||||
bool loadOTCM(const std::string& fileName);
|
bool loadOtcm(const std::string& fileName);
|
||||||
void saveOTCM(const std::string& fileName);
|
void saveOtcm(const std::string& fileName);
|
||||||
|
|
||||||
bool loadOTBM(const std::string& fileName);
|
bool loadOtbm(const std::string& fileName);
|
||||||
//void saveOTBM(const std::string& fileName);
|
//void saveOtbm(const std::string& fileName);
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
void cleanDynamicThings();
|
void cleanDynamicThings();
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "missile.h"
|
#include "missile.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypemanager.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
|
@ -63,7 +63,7 @@ void Missile::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
}
|
}
|
||||||
|
|
||||||
float fraction = m_animationTimer.ticksElapsed() / m_duration;
|
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)
|
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)
|
void Missile::setId(uint32 id)
|
||||||
{
|
{
|
||||||
m_id = id;
|
m_id = id;
|
||||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Missile);
|
m_datType = g_things.getDatType(m_id, DatMissileCategory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
Outfit::Outfit()
|
Outfit::Outfit()
|
||||||
{
|
{
|
||||||
m_category = ThingsType::Creature;
|
m_category = DatCreatureCategory;
|
||||||
m_id = 1;
|
m_id = 1;
|
||||||
resetClothes();
|
resetClothes();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define OUTFIT_H
|
#define OUTFIT_H
|
||||||
|
|
||||||
#include <framework/util/color.h>
|
#include <framework/util/color.h>
|
||||||
#include <otclient/core/thingstype.h>
|
#include <otclient/core/thingtypemanager.h>
|
||||||
|
|
||||||
class Outfit
|
class Outfit
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
void setLegs(int legs) { m_legs = legs; m_legsColor = getColor(legs); }
|
void setLegs(int legs) { m_legs = legs; m_legsColor = getColor(legs); }
|
||||||
void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); }
|
void setFeet(int feet) { m_feet = feet; m_feetColor = getColor(feet); }
|
||||||
void setAddons(int addons) { m_addons = addons; }
|
void setAddons(int addons) { m_addons = addons; }
|
||||||
void setCategory(ThingsType::Categories category) { m_category = category; }
|
void setCategory(DatCategory category) { m_category = category; }
|
||||||
|
|
||||||
void resetClothes();
|
void resetClothes();
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
int getLegs() const { return m_legs; }
|
int getLegs() const { return m_legs; }
|
||||||
int getFeet() const { return m_feet; }
|
int getFeet() const { return m_feet; }
|
||||||
int getAddons() const { return m_addons; }
|
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 getHeadColor() const { return m_headColor; }
|
||||||
Color getBodyColor() const { return m_bodyColor; }
|
Color getBodyColor() const { return m_bodyColor; }
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
Color getFeetColor() const { return m_feetColor; }
|
Color getFeetColor() const { return m_feetColor; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThingsType::Categories m_category;
|
DatCategory m_category;
|
||||||
int m_id, m_head, m_body, m_legs, m_feet, m_addons;
|
int m_id, m_head, m_body, m_legs, m_feet, m_addons;
|
||||||
Color m_headColor, m_bodyColor, m_legsColor, m_feetColor;
|
Color m_headColor, m_bodyColor, m_legsColor, m_feetColor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,12 @@ SpriteManager::SpriteManager()
|
||||||
m_signature = 0;
|
m_signature = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpriteManager::load(const std::string& file)
|
void SpriteManager::termiante()
|
||||||
|
{
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpriteManager::loadSpr(const std::string& file)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_spritesFile = g_resources.openFile(file);
|
m_spritesFile = g_resources.openFile(file);
|
||||||
|
@ -61,6 +66,11 @@ void SpriteManager::unload()
|
||||||
|
|
||||||
ImagePtr SpriteManager::getSpriteImage(int id)
|
ImagePtr SpriteManager::getSpriteImage(int id)
|
||||||
{
|
{
|
||||||
|
enum {
|
||||||
|
SPRITE_SIZE = 32,
|
||||||
|
SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4
|
||||||
|
};
|
||||||
|
|
||||||
if(id == 0)
|
if(id == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -81,11 +91,6 @@ ImagePtr SpriteManager::getSpriteImage(int id)
|
||||||
|
|
||||||
uint16 pixelDataSize = m_spritesFile->getU16();
|
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)));
|
ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE)));
|
||||||
|
|
||||||
uint8 *pixels = image->getPixelData();
|
uint8 *pixels = image->getPixelData();
|
||||||
|
|
|
@ -31,7 +31,9 @@ class SpriteManager
|
||||||
public:
|
public:
|
||||||
SpriteManager();
|
SpriteManager();
|
||||||
|
|
||||||
bool load(const std::string& file);
|
void termiante();
|
||||||
|
|
||||||
|
bool loadSpr(const std::string& file);
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
uint32 getSignature() { return m_signature; }
|
uint32 getSignature() { return m_signature; }
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include "spritemanager.h"
|
#include "spritemanager.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypemanager.h"
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
@ -30,7 +30,8 @@
|
||||||
|
|
||||||
Thing::Thing()
|
Thing::Thing()
|
||||||
{
|
{
|
||||||
m_type = g_thingsType.getEmptyThingType();
|
m_datType = g_things.getNullDatType();
|
||||||
|
m_otbType = g_things.getNullOtbType();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Thing::getStackPriority()
|
int Thing::getStackPriority()
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
#define THING_H
|
#define THING_H
|
||||||
|
|
||||||
#include "declarations.h"
|
#include "declarations.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypedat.h"
|
||||||
|
#include "thingtypeotb.h"
|
||||||
#include <framework/luascript/luaobject.h>
|
#include <framework/luascript/luaobject.h>
|
||||||
|
|
||||||
struct Light
|
struct Light
|
||||||
|
@ -75,51 +76,67 @@ public:
|
||||||
virtual bool isAnimatedText() { return false; }
|
virtual bool isAnimatedText() { return false; }
|
||||||
virtual bool isStaticText() { return false; }
|
virtual bool isStaticText() { return false; }
|
||||||
|
|
||||||
// type related
|
// type shortcuts
|
||||||
bool isGround() { return m_type->getProperty(ThingType::IsGround); }
|
ThingTypeDatPtr getType() { return m_datType; }
|
||||||
bool isFullGround() { return m_type->getProperty(ThingType::IsFullGround); }
|
Size getSize() { return m_datType->getSize(); }
|
||||||
bool isTranslucent() { return m_type->getProperty(ThingType::IsTranslucent); }
|
int getWidth() { return m_datType->getWidth(); }
|
||||||
bool isGroundBorder() { return m_type->getProperty(ThingType::IsGroundBorder); }
|
int getHeight() { return m_datType->getHeight(); }
|
||||||
bool isOnBottom() { return m_type->getProperty(ThingType::IsOnBottom); }
|
Point getDisplacement() { return m_datType->getDisplacement(); }
|
||||||
bool isOnTop() { return m_type->getProperty(ThingType::IsOnTop); }
|
int getDisplacementX() { return m_datType->getDisplacementX(); }
|
||||||
bool isDontHide() { return m_type->getProperty(ThingType::DontHide); }
|
int getDisplacementY() { return m_datType->getDisplacementY(); }
|
||||||
bool isContainer() { return m_type->getProperty(ThingType::IsContainer); }
|
int getExactSize() { return m_datType->getExactSize(); }
|
||||||
bool isForceUse() { return m_type->getProperty(ThingType::IsForceUse); }
|
int getLayers() { return m_datType->getLayers(); }
|
||||||
bool isMultiUse() { return m_type->getProperty(ThingType::IsMultiUse); }
|
int getNumPatternX() { return m_datType->getNumPatternX(); }
|
||||||
bool isRotateable() { return m_type->getProperty(ThingType::IsRotateable); }
|
int getNumPatternY() { return m_datType->getNumPatternY(); }
|
||||||
bool isNotMoveable() { return m_type->getProperty(ThingType::IsNotMovable); }
|
int getNumPatternZ() { return m_datType->getNumPatternZ(); }
|
||||||
bool isNotWalkable() { return m_type->getProperty(ThingType::NotWalkable); }
|
int getAnimationPhases() { return m_datType->getAnimationPhases(); }
|
||||||
bool isPickupable() { return m_type->getProperty(ThingType::IsPickupable); }
|
int getGroundSpeed() { return m_datType->getGroundSpeed(); }
|
||||||
bool isNotPathable() { return m_type->getProperty(ThingType::NotPathable); }
|
int getMaxTextLength() { return m_datType->getMaxTextLength(); }
|
||||||
bool isIgnoreLook() { return m_type->getProperty(ThingType::IgnoreLook); }
|
int getLightLevel() { return m_datType->getLightLevel(); }
|
||||||
bool isHangable() { return m_type->getProperty(ThingType::IsHangable); }
|
int getLightColor() { return m_datType->getLightColor(); }
|
||||||
bool isHookSouth() { return m_type->getProperty(ThingType::HookSouth); }
|
int getMinimapColor() { return m_datType->getMinimapColor(); }
|
||||||
bool isHookEast() { return m_type->getProperty(ThingType::HookEast); }
|
int getLensHelp() { return m_datType->getLensHelp(); }
|
||||||
bool isStackable() { return m_type->getProperty(ThingType::IsStackable); }
|
int getClothSlot() { return m_datType->getClothSlot(); }
|
||||||
bool isAnimateAlways() { return m_type->getProperty(ThingType::AnimateAlways); }
|
int getElevation() { return m_datType->getElevation(); }
|
||||||
bool isLyingCorpse() { return m_type->getProperty(ThingType::IsLyingCorpse); }
|
bool isGround() { return m_datType->isGround(); }
|
||||||
bool blocksProjectile() { return m_type->getProperty(ThingType::BlockProjectile); }
|
bool isGroundBorder() { return m_datType->isGroundBorder(); }
|
||||||
bool isFluid() { return m_type->getProperty(ThingType::IsFluid); }
|
bool isOnBottom() { return m_datType->isOnBottom(); }
|
||||||
bool isFluidContainer() { return m_type->getProperty(ThingType::IsFluidContainer); }
|
bool isOnTop() { return m_datType->isOnTop(); }
|
||||||
Size getDimension() { return Size(m_type->getDimension(ThingType::Width), m_type->getDimension(ThingType::Height)); }
|
bool isContainer() { return m_datType->isContainer(); }
|
||||||
int getDimensionWidth() { return m_type->getDimension(ThingType::Width); }
|
bool isStackable() { return m_datType->isStackable(); }
|
||||||
int getDimensionHeight() { return m_type->getDimension(ThingType::Height); }
|
bool isForceUse() { return m_datType->isForceUse(); }
|
||||||
int getExactSize() { return m_type->getDimension(ThingType::ExactSize); }
|
bool isMultiUse() { return m_datType->isMultiUse(); }
|
||||||
Point getDisplacement() { return Point(m_type->getParameter(ThingType::DisplacementX), m_type->getParameter(ThingType::DisplacementY)); }
|
bool isWritable() { return m_datType->isWritable(); }
|
||||||
int getNumPatternsX() { return m_type->getDimension(ThingType::PatternX); }
|
bool isWritableOnce() { return m_datType->isWritableOnce(); }
|
||||||
int getNumPatternsY() { return m_type->getDimension(ThingType::PatternY); }
|
bool isFluidContainer() { return m_datType->isFluidContainer(); }
|
||||||
int getNumPatternsZ() { return m_type->getDimension(ThingType::PatternZ); }
|
bool isFluid() { return m_datType->isFluid(); }
|
||||||
int getDisplacementX() { return m_type->getParameter(ThingType::DisplacementX); }
|
bool isNotWalkable() { return m_datType->isNotWalkable(); }
|
||||||
int getDisplacementY() { return m_type->getParameter(ThingType::DisplacementY); }
|
bool isNotMoveable() { return m_datType->isNotMoveable(); }
|
||||||
int getLayers() { return m_type->getDimension(ThingType::Layers); }
|
bool blockProjectile() { return m_datType->blockProjectile(); }
|
||||||
int getAnimationPhases() { return m_type->getDimension(ThingType::AnimationPhases); }
|
bool isNotPathable() { return m_datType->isNotPathable(); }
|
||||||
int getGroundSpeed() { return m_type->getParameter(ThingType::GroundSpeed); }
|
bool isPickupable() { return m_datType->isPickupable(); }
|
||||||
int getElevation() { return m_type->getParameter(ThingType::Elevation); }
|
bool isHangable() { return m_datType->isHangable(); }
|
||||||
int getMinimapColor() { return m_type->getParameter(ThingType::MiniMapColor); }
|
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:
|
protected:
|
||||||
Position m_position;
|
Position m_position;
|
||||||
ThingType *m_type;
|
ThingTypeDatPtr m_datType;
|
||||||
|
ThingTypeOtbPtr m_otbType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/core/resourcemanager.h>
|
|
||||||
#include <framework/core/filestream.h>
|
|
||||||
|
|
||||||
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;i<ThingType::LastProperty;++i) {
|
|
||||||
int property = fin->getU8();
|
|
||||||
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];
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/graphics/graphics.h>
|
|
||||||
#include <framework/graphics/texture.h>
|
|
||||||
#include <framework/graphics/image.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/graphics/declarations.h>
|
|
||||||
#include <framework/graphics/coordsbuffer.h>
|
|
||||||
|
|
||||||
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<int, LastDimension> m_dimensions;
|
|
||||||
std::array<int, LastParameter> m_parameters;
|
|
||||||
std::array<bool, LastProperty> m_properties;
|
|
||||||
std::vector<int> m_spritesIndex;
|
|
||||||
|
|
||||||
std::vector<TexturePtr> m_textures;
|
|
||||||
std::vector<std::vector<Rect> > m_texturesFramesRects;
|
|
||||||
std::vector<std::vector<Rect> > m_texturesFramesOriginRects;
|
|
||||||
std::vector<std::vector<Point> > m_texturesFramesOffsets;
|
|
||||||
|
|
||||||
friend class ThingsType;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,392 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/graphics/graphics.h>
|
||||||
|
#include <framework/graphics/texture.h>
|
||||||
|
#include <framework/graphics/image.h>
|
||||||
|
#include <framework/graphics/texturemanager.h>
|
||||||
|
#include <framework/core/filestream.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/core/declarations.h>
|
||||||
|
#include <framework/graphics/declarations.h>
|
||||||
|
#include <framework/graphics/coordsbuffer.h>
|
||||||
|
#include <framework/luascript/luaobject.h>
|
||||||
|
#include <framework/net/server.h>
|
||||||
|
|
||||||
|
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<true> m_null;
|
||||||
|
|
||||||
|
std::vector<int> m_spritesIndex;
|
||||||
|
std::vector<TexturePtr> m_textures;
|
||||||
|
std::vector<std::vector<Rect>> m_texturesFramesRects;
|
||||||
|
std::vector<std::vector<Rect>> m_texturesFramesOriginRects;
|
||||||
|
std::vector<std::vector<Point>> 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<false> m_isGround;
|
||||||
|
Boolean<false> m_isGroundBorder;
|
||||||
|
Boolean<false> m_isOnBottom;
|
||||||
|
Boolean<false> m_isOnTop;
|
||||||
|
Boolean<false> m_isContainer;
|
||||||
|
Boolean<false> m_isStackable;
|
||||||
|
Boolean<false> m_isForceUse;
|
||||||
|
Boolean<false> m_isMultiUse;
|
||||||
|
Boolean<false> m_isWritable;
|
||||||
|
Boolean<false> m_isWritableOnce;
|
||||||
|
Boolean<false> m_isFluidContainer;
|
||||||
|
Boolean<false> m_isFluid;
|
||||||
|
Boolean<false> m_isNotWalkable;
|
||||||
|
Boolean<false> m_isNotMoveable;
|
||||||
|
Boolean<false> m_blockProjectile;
|
||||||
|
Boolean<false> m_isNotPathable;
|
||||||
|
Boolean<false> m_isPickupable;
|
||||||
|
Boolean<false> m_isHangable;
|
||||||
|
Boolean<false> m_isHookSouth;
|
||||||
|
Boolean<false> m_isHookEast;
|
||||||
|
Boolean<false> m_isRotateable;
|
||||||
|
Boolean<false> m_hasLight;
|
||||||
|
Boolean<false> m_isDontHide;
|
||||||
|
Boolean<false> m_isTranslucent;
|
||||||
|
Boolean<false> m_hasDisplacement;
|
||||||
|
Boolean<false> m_hasElevation;
|
||||||
|
Boolean<false> m_isLyingCorpse;
|
||||||
|
Boolean<false> m_isAnimateAlways;
|
||||||
|
Boolean<false> m_hasMiniMapColor;
|
||||||
|
Boolean<false> m_hasLensHelp;
|
||||||
|
Boolean<false> m_isFullGround;
|
||||||
|
Boolean<false> m_isIgnoreLook;
|
||||||
|
Boolean<false> m_isCloth;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/core/resourcemanager.h>
|
||||||
|
#include <framework/core/filestream.h>
|
||||||
|
|
||||||
|
#define TIXML_USE_STL // use STL strings instead.
|
||||||
|
#include <framework/thirdparty/tinyxml.h>
|
||||||
|
|
||||||
|
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<uint16>(element->Attribute("id"));
|
||||||
|
uint16 idEx = 0;
|
||||||
|
if (!id) {
|
||||||
|
bool found = false;
|
||||||
|
// fallback into reading fromid and toid
|
||||||
|
uint16 fromid = stdext::unsafe_cast<uint16>(element->Attribute("fromid"));
|
||||||
|
uint16 toid = stdext::unsafe_cast<uint16>(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<double>(stdext::unsafe_cast<double>(value) / 100.f);
|
||||||
|
} else if (key == "containerSize") {
|
||||||
|
int containerSize = stdext::unsafe_cast<int>(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<int>(value);
|
||||||
|
} else if (key == "charges") {
|
||||||
|
iType->charges = stdext::unsafe_cast<int>(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];
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/global.h>
|
||||||
|
#include <framework/core/declarations.h>
|
||||||
|
|
||||||
|
#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
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/core/filestream.h>
|
||||||
|
|
||||||
|
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;i<OtbLastAttrib; ++i) {
|
||||||
|
int attr = fin->getU8();
|
||||||
|
|
||||||
|
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?");
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 <framework/core/declarations.h>
|
||||||
|
#include <framework/luascript/luaobject.h>
|
||||||
|
|
||||||
|
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<true> m_null;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "thingstype.h"
|
#include "thingtypemanager.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "localplayer.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);
|
thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate);
|
||||||
|
|
||||||
if(thing->isLyingCorpse()) {
|
if(thing->isLyingCorpse()) {
|
||||||
redrawPreviousTopW = std::max(thing->getDimensionWidth(), redrawPreviousTopW);
|
redrawPreviousTopW = std::max(thing->getWidth(), redrawPreviousTopW);
|
||||||
redrawPreviousTopH = std::max(thing->getDimensionHeight(), redrawPreviousTopH);
|
redrawPreviousTopH = std::max(thing->getHeight(), redrawPreviousTopH);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_drawElevation += thing->getElevation();
|
m_drawElevation += thing->getElevation();
|
||||||
|
@ -425,7 +425,7 @@ bool Tile::isFullyOpaque()
|
||||||
bool Tile::isLookPossible()
|
bool Tile::isLookPossible()
|
||||||
{
|
{
|
||||||
for(const ThingPtr& thing : m_things) {
|
for(const ThingPtr& thing : m_things) {
|
||||||
if(thing->blocksProjectile())
|
if(thing->blockProjectile())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <otclient/core/player.h>
|
#include <otclient/core/player.h>
|
||||||
#include <otclient/core/localplayer.h>
|
#include <otclient/core/localplayer.h>
|
||||||
#include <otclient/core/map.h>
|
#include <otclient/core/map.h>
|
||||||
#include <otclient/core/thingstype.h>
|
#include <otclient/core/thingtypemanager.h>
|
||||||
#include <otclient/core/spritemanager.h>
|
#include <otclient/core/spritemanager.h>
|
||||||
#include <otclient/core/shadermanager.h>
|
#include <otclient/core/shadermanager.h>
|
||||||
#include <otclient/net/protocolgame.h>
|
#include <otclient/net/protocolgame.h>
|
||||||
|
@ -47,16 +47,17 @@
|
||||||
|
|
||||||
void OTClient::registerLuaFunctions()
|
void OTClient::registerLuaFunctions()
|
||||||
{
|
{
|
||||||
g_lua.registerSingletonClass("g_thingsType");
|
g_lua.registerSingletonClass("g_things");
|
||||||
g_lua.bindSingletonFunction("g_thingsType", "load", &ThingsType::load, &g_thingsType);
|
g_lua.bindSingletonFunction("g_things", "loadDat", &ThingTypeManager::loadDat, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_thingsType", "isLoaded", &ThingsType::isLoaded, &g_thingsType);
|
g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_thingsType", "getSignature", &ThingsType::getSignature, &g_thingsType);
|
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.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", "unload", &SpriteManager::unload, &g_sprites);
|
||||||
g_lua.bindSingletonFunction("g_sprites", "isLoaded", &SpriteManager::isLoaded, &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.bindSingletonFunction("g_sprites", "getSpritesCount", &SpriteManager::getSpritesCount, &g_sprites);
|
||||||
|
|
||||||
g_lua.registerSingletonClass("g_map");
|
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", "removeCreatureById", &Map::removeCreatureById, &g_map);
|
||||||
g_lua.bindSingletonFunction("g_map", "getSpectators", &Map::getSpectators, &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", "findPath", &Map::findPath, &g_map);
|
||||||
g_lua.bindSingletonFunction("g_map", "loadOTBM", &Map::loadOTBM, &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", "saveOtbm", &Map::saveOtbm, &g_map);
|
||||||
g_lua.bindSingletonFunction("g_map", "loadOTCM", &Map::loadOTCM, &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", "saveOtcm", &Map::saveOtcm, &g_map);
|
||||||
|
|
||||||
g_lua.registerSingletonClass("g_game");
|
g_lua.registerSingletonClass("g_game");
|
||||||
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
|
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "protocolgame.h"
|
#include "protocolgame.h"
|
||||||
|
|
||||||
#include <otclient/core/localplayer.h>
|
#include <otclient/core/localplayer.h>
|
||||||
#include <otclient/core/thingstype.h>
|
#include <otclient/core/thingtypemanager.h>
|
||||||
#include <otclient/core/game.h>
|
#include <otclient/core/game.h>
|
||||||
#include <otclient/core/map.h>
|
#include <otclient/core/map.h>
|
||||||
#include <otclient/core/item.h>
|
#include <otclient/core/item.h>
|
||||||
|
@ -1317,7 +1317,7 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
|
||||||
|
|
||||||
int lookType = msg->getU16();
|
int lookType = msg->getU16();
|
||||||
if(lookType != 0) {
|
if(lookType != 0) {
|
||||||
outfit.setCategory(ThingsType::Creature);
|
outfit.setCategory(DatCreatureCategory);
|
||||||
int head = msg->getU8();
|
int head = msg->getU8();
|
||||||
int body = msg->getU8();
|
int body = msg->getU8();
|
||||||
int legs = msg->getU8();
|
int legs = msg->getU8();
|
||||||
|
@ -1334,11 +1334,11 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
|
||||||
else {
|
else {
|
||||||
int lookTypeEx = msg->getU16();
|
int lookTypeEx = msg->getU16();
|
||||||
if(lookTypeEx == 0) {
|
if(lookTypeEx == 0) {
|
||||||
outfit.setCategory(ThingsType::Effect);
|
outfit.setCategory(DatEffectCategory);
|
||||||
outfit.setId(13);
|
outfit.setId(13);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outfit.setCategory(ThingsType::Item);
|
outfit.setCategory(DatItemCategory);
|
||||||
outfit.setId(lookTypeEx);
|
outfit.setId(lookTypeEx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1492,7 +1492,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id)
|
||||||
|
|
||||||
ItemPtr item = Item::create(id);
|
ItemPtr item = Item::create(id);
|
||||||
if(item->getId() == 0)
|
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())
|
if(item->isStackable() || item->isFluidContainer() || item->isFluid())
|
||||||
item->setCountOrSubType(msg->getU8());
|
item->setCountOrSubType(msg->getU8());
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <otclient/core/game.h>
|
#include <otclient/core/game.h>
|
||||||
#include <otclient/core/map.h>
|
#include <otclient/core/map.h>
|
||||||
#include <otclient/core/shadermanager.h>
|
#include <otclient/core/shadermanager.h>
|
||||||
|
#include "core/spritemanager.h"
|
||||||
#include <framework/core/configmanager.h>
|
#include <framework/core/configmanager.h>
|
||||||
|
|
||||||
OTClient g_otclient;
|
OTClient g_otclient;
|
||||||
|
@ -37,6 +38,7 @@ void OTClient::init(const std::vector<std::string>& args)
|
||||||
registerLuaFunctions();
|
registerLuaFunctions();
|
||||||
|
|
||||||
g_shaders.init();
|
g_shaders.init();
|
||||||
|
g_things.init();
|
||||||
|
|
||||||
//TODO: restore options
|
//TODO: restore options
|
||||||
/*
|
/*
|
||||||
|
@ -77,7 +79,8 @@ void OTClient::init(const std::vector<std::string>& args)
|
||||||
|
|
||||||
void OTClient::terminate()
|
void OTClient::terminate()
|
||||||
{
|
{
|
||||||
|
g_map.terminate();
|
||||||
|
g_things.terminate();
|
||||||
|
g_sprites.termiante();
|
||||||
g_shaders.terminate();
|
g_shaders.terminate();
|
||||||
g_map.clean();
|
|
||||||
g_thingsType.unload();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue