parent
f3499efe83
commit
96c363d997
@ -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
|
@ -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
|
||||
|
Loading…
Reference in new issue