From 0fa61333faf31579e46e7db11fbaf1e589941edf Mon Sep 17 00:00:00 2001 From: Henrique Date: Sat, 12 Nov 2011 04:24:32 -0200 Subject: [PATCH] thingstype rework --- src/otclient/core/creature.cpp | 10 +- src/otclient/core/effect.cpp | 2 +- src/otclient/core/item.cpp | 40 ++--- src/otclient/core/map.cpp | 4 +- src/otclient/core/missile.cpp | 2 +- src/otclient/core/thing.cpp | 30 ++-- src/otclient/core/thing.h | 2 +- src/otclient/core/thingstype.cpp | 223 +++++++------------------ src/otclient/core/thingstype.h | 19 ++- src/otclient/core/thingtype.h | 163 ++++++++---------- src/otclient/core/tile.cpp | 24 +-- src/otclient/net/protocolgame.h | 2 +- src/otclient/net/protocolgameparse.cpp | 8 +- 13 files changed, 199 insertions(+), 330 deletions(-) diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 67c08b57..17b4a6db 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -47,7 +47,7 @@ void Creature::draw(const Point& p) const ThingType& type = getType(); // Render creature - for(m_yPattern = 0; m_yPattern < type.yPattern; m_yPattern++) { + for(m_yPattern = 0; m_yPattern < type.dimensions[ThingType::PatternY]; m_yPattern++) { // continue if we dont have this addon. if(m_yPattern > 0 && !(m_outfit.addons & (1 << (m_yPattern-1)))) @@ -57,7 +57,7 @@ void Creature::draw(const Point& p) internalDraw(p + m_walkOffset, 0); // draw mask if exists - if(type.layers > 1) { + if(type.dimensions[ThingType::Layers] > 1) { // switch to blend color mode g_graphics.bindBlendFunc(Fw::BlendColorzing); @@ -187,7 +187,7 @@ void Creature::walk(const Position& position, bool inverse) ItemPtr ground = g_map.getTile(position)->getGround(); if(ground) - groundSpeed = ground->getType().groundSpeed; + groundSpeed = ground->getType().parameters[ThingType::GroundSpeed]; float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed; walkTime = (walkTime == 0) ? 1000 : walkTime; @@ -233,7 +233,7 @@ void Creature::updateWalk() } int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5; - m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.animationPhases - 1)) + 1; + m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1; g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel); if(totalPixelsWalked == 32) @@ -272,7 +272,7 @@ void Creature::setDirection(Otc::Direction direction) const ThingType& Creature::getType() { - return g_thingsType.getCreatureType(m_outfit.type); + return g_thingsType.getThingType(m_outfit.type, ThingsType::Creature); } void Creature::onHealthPercentChange(int) diff --git a/src/otclient/core/effect.cpp b/src/otclient/core/effect.cpp index b37a5e2b..e75c51c7 100644 --- a/src/otclient/core/effect.cpp +++ b/src/otclient/core/effect.cpp @@ -55,5 +55,5 @@ void Effect::startAnimation() const ThingType& Effect::getType() { - return g_thingsType.getEffectType(m_id); + return g_thingsType.getThingType(m_id, ThingsType::Effect); } diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index 7d566d80..d28ff269 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -34,12 +34,12 @@ Item::Item() : Thing() void Item::draw(const Point& p) { - const ThingType& type = g_thingsType.getItemType(m_id); + const ThingType& type = getType(); - if(type.animationPhases > 1) - m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.animationPhases)) / TICKS_PER_FRAME; + if(type.dimensions[ThingType::AnimationPhases] > 1) + m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME; - for(int b = 0; b < type.layers; b++) + for(int b = 0; b < type.dimensions[ThingType::Layers]; b++) internalDraw(p, b); } @@ -52,25 +52,25 @@ void Item::setData(int count) const ThingType& Item::getType() { - return g_thingsType.getItemType(m_id); + return g_thingsType.getThingType(m_id, ThingsType::Item); } void Item::onPositionChange(const Position&) { - const ThingType& type = g_thingsType.getItemType(m_id); + const ThingType& type = getType(); - if(type.isNotMoveable) { - m_xPattern = m_position.x % type.xPattern; - m_yPattern = m_position.y % type.yPattern; - m_zPattern = m_position.z % type.zPattern; + if(type.properties[ThingType::NotMovable]) { + m_xPattern = m_position.x % type.dimensions[ThingType::PatternX]; + m_yPattern = m_position.y % type.dimensions[ThingType::PatternY]; + m_zPattern = m_position.z % type.dimensions[ThingType::PatternZ]; } } void Item::onDataChange(int) { - const ThingType& type = g_thingsType.getItemType(m_id); + const ThingType& type = getType(); - if(type.isStackable && type.xPattern == 4 && type.yPattern == 2) { + if(type.properties[ThingType::IsStackable] && type.dimensions[ThingType::PatternX] == 4 && type.dimensions[ThingType::PatternY] == 2) { if(m_data < 5) { m_xPattern = m_data-1; m_yPattern = 0; @@ -92,15 +92,15 @@ void Item::onDataChange(int) m_yPattern = 1; } } - else if(type.isHangable) { - if(type.isHookSouth) { - m_xPattern = type.xPattern >= 2 ? 1 : 0; + else if(type.properties[ThingType::IsHangable]) { + if(type.properties[ThingType::HookSouth]) { + m_xPattern = type.dimensions[ThingType::PatternX] >= 2 ? 1 : 0; } - else if(type.isHookEast) { - m_xPattern = type.xPattern >= 3 ? 2 : 0; + else if(type.properties[ThingType::HookEast]) { + m_xPattern = type.dimensions[ThingType::PatternX] >= 3 ? 2 : 0; } } - else if(type.isSplash || type.isFluidContainer) { + else if(type.properties[ThingType::IsFluid] || type.properties[ThingType::IsFluidContainer]) { int var = 0; // TODO: find out what the heck does it mean switch(m_data) { @@ -163,7 +163,7 @@ void Item::onDataChange(int) break; } - m_xPattern = (var & 3) % type.xPattern; - m_yPattern = (var >> 2) % type.yPattern; + m_xPattern = (var & 3) % type.dimensions[ThingType::PatternX]; + m_yPattern = (var >> 2) % type.dimensions[ThingType::PatternY]; } } diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index 3ae4bc75..e39785db 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -129,7 +129,7 @@ int Map::getFirstVisibleFloor() if(TilePtr tile = m_tiles[upperPos]) { if(ThingPtr firstThing = tile->getThing(0)) { const ThingType type = firstThing->getType(); - if((type.isGround || type.isOnBottom) && !type.isDontHide) { + if((type.properties[ThingType::IsGround] || type.properties[ThingType::IsOnBottom]) && !type.properties[ThingType::DontHide]) { firstFloor = upperPos.z + 1; break; } @@ -138,7 +138,7 @@ int Map::getFirstVisibleFloor() if(TilePtr tile = m_tiles[perspectivePos]) { if(ThingPtr firstThing = tile->getThing(0)) { const ThingType type = firstThing->getType(); - if((type.isGround || type.isOnBottom) && !type.isDontHide) { + if((type.properties[ThingType::IsGround] || type.properties[ThingType::IsOnBottom]) && !type.properties[ThingType::DontHide]) { firstFloor = perspectivePos.z + 1; break; } diff --git a/src/otclient/core/missile.cpp b/src/otclient/core/missile.cpp index db0298f9..ea9ead9d 100644 --- a/src/otclient/core/missile.cpp +++ b/src/otclient/core/missile.cpp @@ -119,5 +119,5 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition) const ThingType& Missile::getType() { - return g_thingsType.getShotType(m_id); + return g_thingsType.getThingType(m_id, ThingsType::Missile); } diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index fd5f7760..5a908da8 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -52,15 +52,15 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask) { const ThingType& type = getType(); - for(int yi = 0; yi < type.height; yi++) { - for(int xi = 0; xi < type.width; xi++) { - int sprIndex = ((((((m_animation % type.animationPhases) - * type.zPattern + m_zPattern) - * type.yPattern + m_yPattern) - * type.xPattern + m_xPattern) - * type.layers + layers) - * type.height + yi) - * type.width + xi; + for(int yi = 0; yi < type.dimensions[ThingType::Height]; yi++) { + for(int xi = 0; xi < type.dimensions[ThingType::Width]; xi++) { + int sprIndex = ((((((m_animation % type.dimensions[ThingType::AnimationPhases]) + * type.dimensions[ThingType::PatternZ] + m_zPattern) + * type.dimensions[ThingType::PatternY] + m_yPattern) + * type.dimensions[ThingType::PatternX] + m_xPattern) + * type.dimensions[ThingType::Layers] + layers) + * type.dimensions[ThingType::Height] + yi) + * type.dimensions[ThingType::Width] + xi; int spriteId = type.sprites[sprIndex]; if(!spriteId) @@ -68,8 +68,8 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask) TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask); - Rect drawRect((p.x - xi*32) - type.xDisplacement, - (p.y - yi*32) - type.yDisplacement, + Rect drawRect((p.x - xi*32) - type.parameters[ThingType::DisplacementX], + (p.y - yi*32) - type.parameters[ThingType::DisplacementY], 32, 32); g_graphics.drawTexturedRect(drawRect, spriteTex); } @@ -79,13 +79,13 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask) int Thing::getStackPriority() { const ThingType& type = getType(); - if(type.isGround) + if(type.properties[ThingType::IsGround]) return 0; - else if(type.isGroundClip) + else if(type.properties[ThingType::IsGroundBorder]) return 1; - else if(type.isOnBottom) + else if(type.properties[ThingType::IsOnBottom]) return 2; - else if(type.isOnTop) + else if(type.properties[ThingType::IsOnTop]) return 3; else if(asCreature()) return 4; diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index 9741dc38..d67519fa 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -48,7 +48,7 @@ public: Position getPosition() const { return m_position; } int getStackPriority(); virtual const ThingType& getType() = 0; - int getAnimationPhases() { return getType().animationPhases; } + int getAnimationPhases() { return getType().dimensions[ThingType::AnimationPhases]; } virtual void onIdChange(int) {} virtual void onPositionChange(const Position&) {} diff --git a/src/otclient/core/thingstype.cpp b/src/otclient/core/thingstype.cpp index 7f39781a..6f591a0b 100644 --- a/src/otclient/core/thingstype.cpp +++ b/src/otclient/core/thingstype.cpp @@ -34,26 +34,18 @@ bool ThingsType::load(const std::string& file) g_resources.loadFile(file, fin); m_signature = Fw::getU32(fin); - int numItems = Fw::getU16(fin); - int numCreatures = Fw::getU16(fin); - int numEffects = Fw::getU16(fin); - int numShots = Fw::getU16(fin); - m_itemsType.resize(numItems-100); - for(int id = 100; id < numItems; ++id) - parseThingType(fin, m_itemsType[id - 100]); + int numThings[LastCategory]; + for(int i = 0; i < LastCategory; ++i) + numThings[i] = Fw::getU16(fin); - m_creaturesType.resize(numCreatures); - for(int id = 0; id < numCreatures; ++id) - parseThingType(fin, m_creaturesType[id]); + numThings[Item] -= 100; - m_effectsType.resize(numEffects); - for(int id = 0; id < numEffects; ++id) - parseThingType(fin, m_effectsType[id]); - - m_shotsType.resize(numShots); - for(int id = 0; id < numShots; ++id) - parseThingType(fin, m_shotsType[id]); + for(int i = 0; i < LastCategory; ++i) { + m_things[i].resize(numThings[i]); + for(int id = 0; id < numThings[i]; ++id) + parseThingType(fin, m_things[i][id]); + } return true; } catch(std::exception& e) { @@ -64,162 +56,67 @@ bool ThingsType::load(const std::string& file) void ThingsType::unload() { - m_itemsType.clear(); - m_creaturesType.clear(); - m_effectsType.clear(); - m_shotsType.clear(); + for(int i = 0; i < LastCategory; ++i) + m_things[i].clear(); } void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType) { assert(fin.good()); - bool done = false; - while(!done) { - uint8 opt = Fw::getU8(fin); - - switch(opt) { - case Otc::DatGround: // Grounds, must be drawn first - thingType.groundSpeed = Fw::getU16(fin); - thingType.isGround = true; - break; - case Otc::DatGroundClip: // Objects that clips (has transparent pixels) and must be drawn just after ground (e.g: ground borders) - thingType.isGroundClip = true; - break; - case Otc::DatOnBottom: // Bottom items, must be drawn above general items and below creatures (e.g: stairs) - thingType.isOnBottom = true; - break; - case Otc::DatOnTop: // Top items, must be drawn above creatures (e.g: doors) - thingType.isOnTop = true; - break; - case Otc::DatContainer: // Containers - thingType.isContainer = true; - break; - case Otc::DatStackable: // Stackable - thingType.isStackable = true; - break; - case Otc::DatForceUse: // Items that are automatically used when step over? - thingType.isForceUse = true; - break; - case Otc::DatMultiUse: // Usable items - thingType.isMultiUse = true; - break; - case Otc::DatWritable: // Writable - thingType.isWritable = true; - thingType.maxTextLength = Fw::getU16(fin); - break; - case Otc::DatWritableOnce: // Writable once. objects that can't be edited by players - thingType.isWritableOnce = true; - thingType.maxTextLength = Fw::getU16(fin); - break; - case Otc::DatFluidContainer: // Fluid containers - thingType.isFluidContainer = true; - break; - case Otc::DatSplash: // Splashes - thingType.isSplash = true; - break; - case Otc::DatBlockWalk: // Blocks solid objects (creatures, walls etc) - thingType.isNotWalkable = true; - break; - case Otc::DatNotMovable: // Not movable - thingType.isNotMoveable = true; - break; - case Otc::DatBlockProjectile: // Blocks missiles (walls, magic wall etc) - thingType.isUnsight = true; - break; - case Otc::DatBlockPathFind: // Blocks pathfind algorithms (monsters) - thingType.isNotPathable = true; - break; - case Otc::DatPickupable: // Pickupable - thingType.isPickupable = true; - break; - case Otc::DatHangable: // Hangable objects (wallpaper etc) - thingType.isHangable = true; - break; - case Otc::DatHookSouth: // Horizontal walls - thingType.isHookSouth = true; - break; - case Otc::DatHookEast: // Vertical walls - thingType.isHookEast = true; - break; - case Otc::DatRotable: // Rotable - thingType.isRotable = true; - break; - case Otc::DatLight: // Light info - thingType.hasLight = true; - thingType.lightLevel = Fw::getU16(fin); - thingType.lightColor = Fw::getU16(fin); - break; - case Otc::DatDontHide: // A few monuments that are not supposed to be hidden by floors - thingType.isDontHide = true; - break; - case Otc::DatTranslucent: // Grounds that are translucent - thingType.isTranslucent = true; - break; - case Otc::DatDisplacement: // Must shift draw - thingType.xDisplacement = Fw::getU16(fin); - thingType.yDisplacement = Fw::getU16(fin); - break; - case Otc::DatElevation: // Must elevate draw - thingType.elevation = Fw::getU16(fin); - break; - case Otc::DatLyingCorpse: // Some corpses - thingType.isLyingCorpse = true; - break; - case Otc::DatAnimateAlways: // Unknown, check if firesword is a kind of AnimateAlways. - thingType.isAnimatedAlways = true; - break; - case Otc::DatMinimapColor: // Minimap color - thingType.hasMiniMapColor = true; - thingType.miniMapColor = Fw::getU16(fin); - break; - case Otc::DatLensHelp: // Used for giving players tips? - thingType.isLensHelp = true; - thingType.lensHelp = Fw::getU16(fin); - break; - case Otc::DatFullGround: // Grounds that has no transparent pixels - thingType.isFullGround = true; - break; - case Otc::DatIgnoreLook: // Ignore look, then looks at the item on the bottom of it - thingType.isIgnoreLook = true; - break; - case Otc::DatCloth: // Clothes - thingType.isCloth = true; - thingType.clothSlot = Fw::getU16(fin); - break; - case Otc::DatLastOpt: - done = true; - break; - default: - throw std::runtime_error(Fw::mkstr("unknown .dat byte code: ", (int)opt)); + while(true) { + int property = Fw::getU8(fin); + if(property == ThingType::LastPropertyValue) + break; + + thingType.properties[property] = true; + + if(property == ThingType::IsGround) + thingType.parameters[ThingType::GroundSpeed] = Fw::getU16(fin); + else if(property == ThingType::IsWritable || property == ThingType::IsWritableOnce) + thingType.parameters[ThingType::MaxTextLenght] = Fw::getU16(fin); + else if(property == ThingType::HasLight) { + thingType.parameters[ThingType::LightLevel] = Fw::getU16(fin); + thingType.parameters[ThingType::LightColor] = Fw::getU16(fin); } + else if(property == ThingType::HasDisplacement) { + thingType.parameters[ThingType::DisplacementX] = Fw::getU16(fin); + thingType.parameters[ThingType::DisplacementY] = Fw::getU16(fin); + } + else if(property == ThingType::HasElevation) + thingType.parameters[ThingType::Elevation] = Fw::getU16(fin); + else if(property == ThingType::MiniMap) + thingType.parameters[ThingType::MiniMapColor] = Fw::getU16(fin); + else if(property == ThingType::LensHelp) + thingType.parameters[ThingType::LensHelpParameter] = Fw::getU16(fin); + else if(property == ThingType::Cloth) + thingType.parameters[ThingType::ClothSlot] = Fw::getU16(fin); } - thingType.width = Fw::getU8(fin); - thingType.height = Fw::getU8(fin); - - if(thingType.width > 1 || thingType.height > 1) - thingType.exactSize = Fw::getU8(fin); - else - thingType.exactSize = 32; - - thingType.layers = Fw::getU8(fin); - thingType.xPattern = Fw::getU8(fin); - thingType.yPattern = Fw::getU8(fin); - thingType.zPattern = Fw::getU8(fin); - thingType.animationPhases = Fw::getU8(fin); - if(thingType.animationPhases > 1) - thingType.isAnimation = true; - - int totalSprites = thingType.width - * thingType.height - * thingType.layers - * thingType.xPattern - * thingType.yPattern - * thingType.zPattern - * thingType.animationPhases; + int totalSprites = 1; + for(int i = 0; i < ThingType::LastDimension; ++i) { + if(i == ThingType::ExactSize && thingType.dimensions[ThingType::Width] <= 1 && thingType.dimensions[ThingType::Height] <= 1) { + thingType.dimensions[i] = 32; + continue; + } + + thingType.dimensions[i] = Fw::getU8(fin); + + if(i != ThingType::ExactSize) + totalSprites *= thingType.dimensions[i]; + } thingType.sprites.resize(totalSprites); - for(uint16 i = 0; i < totalSprites; i++) + for(int i = 0; i < totalSprites; i++) thingType.sprites[i] = Fw::getU16(fin); } + +ThingType& ThingsType::getThingType(uint16 id, Categories category) +{ + if(category == Item) + id -= 100; + + assert(id < m_things[category].size()); + + return m_things[category][id]; +} diff --git a/src/otclient/core/thingstype.h b/src/otclient/core/thingstype.h index 3bccfae2..787513df 100644 --- a/src/otclient/core/thingstype.h +++ b/src/otclient/core/thingstype.h @@ -29,25 +29,28 @@ class ThingsType { public: + + enum Categories { + Item = 0, + Creature, + Effect, + Missile, + LastCategory + }; + bool load(const std::string& file); void unload(); void parseThingType(std::stringstream& fin, ThingType& thingType); - ThingType& getItemType(uint16 id) { return m_itemsType[id - 100]; } - ThingType& getCreatureType(uint16 id) { return m_creaturesType[id]; } - ThingType& getEffectType(uint16 id) { return m_effectsType[id]; } - ThingType& getShotType(uint16 id) { return m_shotsType[id]; } + ThingType& getThingType(uint16 id, Categories category); uint32 getSignature() { return m_signature; } private: uint32 m_signature; - ThingTypeList m_itemsType; - ThingTypeList m_creaturesType; - ThingTypeList m_effectsType; - ThingTypeList m_shotsType; + ThingTypeList m_things[LastCategory]; }; extern ThingsType g_thingsType; diff --git a/src/otclient/core/thingtype.h b/src/otclient/core/thingtype.h index 10b58dc7..46dd515a 100644 --- a/src/otclient/core/thingtype.h +++ b/src/otclient/core/thingtype.h @@ -27,106 +27,75 @@ struct ThingType { - ThingType() { - layers = 0; - width = height = 0; - exactSize = 0; - xPattern = yPattern = zPattern = 0; - animationPhases = 0; - xDisplacement = yDisplacement = 0; - elevation = 0; - - isGround = false; - isGroundClip = false; - isOnBottom = false; - isOnTop = false; - isContainer = false; - isStackable = false; - isForceUse = false; - isMultiUse = false; - isWritable = false; - isWritableOnce = false; - isFluidContainer = false; - isSplash = false; - isNotWalkable = false; - isNotMoveable = false; - isUnsight = false; - isNotPathable = false; - isPickupable = false; - isHangable = false; - isHookSouth = false; - isHookEast = false; - isRotable = false; - isDontHide = false; - isTranslucent = false; - isLyingCorpse = false; - isAnimatedAlways = false; - isLensHelp = false; - isFullGround = false; - isIgnoreLook = false; - isCloth = false; - isAnimation = false; - hasLight = false; - hasMiniMapColor = false; - - groundSpeed = 0; - fluidParam = 0; - maxTextLength = 0; - lightLevel = lightColor = 0; - miniMapColor = 0; - lensHelp = 0; - clothSlot = 0; - } - - uint8 layers; - uint8 width, height; - uint8 exactSize; - uint8 xPattern, yPattern, zPattern; - uint8 animationPhases; - uint16 xDisplacement, yDisplacement; - uint16 elevation; + enum Dimensions { + Width = 0, + Height, + ExactSize, + Layers, + PatternX, + PatternY, + PatternZ, + AnimationPhases, + LastDimension + }; + std::array dimensions; std::vector sprites; - bool isGround; - bool isGroundClip; - bool isOnBottom; - bool isOnTop; - bool isContainer; - bool isStackable; - bool isForceUse; - bool isMultiUse; - bool isWritable; - bool isWritableOnce; - bool isFluidContainer; - bool isSplash; - bool isNotWalkable; - bool isNotMoveable; - bool isUnsight; - bool isNotPathable; - bool isPickupable; - bool isHangable; - bool isHookSouth; - bool isHookEast; - bool isRotable; - bool isDontHide; - bool isTranslucent; - bool isLyingCorpse; - bool isAnimatedAlways; - bool isLensHelp; - bool isFullGround; - bool isIgnoreLook; - bool isCloth; - bool isAnimation; - bool hasLight; - bool hasMiniMapColor; + enum Properties { + IsGround = 0, + IsGroundBorder, + IsOnBottom, + IsOnTop, + IsContainer, + IsStackable, + IsForceUse, + IsMultiUse, + IsWritable, + IsWritableOnce, + IsFluidContainer, + IsFluid, + NotWalkable, + NotMovable, + BlockProjectile, + NotPathable, + Pickupable, + IsHangable, + HookSouth, + HookEast, + IsRotable, + HasLight, + DontHide, + IsTranslucent, + HasDisplacement, + HasElevation, + IsLyingCorpse, + AnimateAlways, + MiniMap, + LensHelp, + IsFullGround, + IgnoreLook, + Cloth, + Animation, + LastProperty, + LastPropertyValue = 255 + }; + std::array properties; - uint16 groundSpeed; - uint8 fluidParam; - uint16 maxTextLength; - uint16 lightLevel, lightColor; - uint16 miniMapColor; - uint16 lensHelp; - uint16 clothSlot; + enum Parameters { + GroundSpeed = 0, + Fluid, + MaxTextLenght, + LightLevel, + LightColor, + MiniMapColor, + LensHelpParameter, + ClothSlot, + DisplacementX, + DisplacementY, + Elevation, + LastParameter + }; + std::array parameters; }; typedef std::vector ThingTypeList; diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index e9a5bff0..8f5b8ef1 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -43,10 +43,10 @@ void Tile::draw(const Point& p) // first bottom items for(const ThingPtr& thing : m_things) { const ThingType& type = thing->getType(); - if(!type.isGround && !type.isGroundClip && !type.isOnBottom) + if(!type.properties[ThingType::IsGround] && !type.properties[ThingType::IsGroundBorder] && !type.properties[ThingType::IsOnBottom]) break; thing->draw(p - m_drawElevation); - m_drawElevation += type.elevation; + m_drawElevation += type.parameters[ThingType::Elevation]; if(m_drawElevation > MAX_DRAW_ELEVATION) m_drawElevation = MAX_DRAW_ELEVATION; } @@ -55,10 +55,10 @@ void Tile::draw(const Point& p) for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { const ThingPtr& thing = *it; const ThingType& type = thing->getType(); - if(thing->asCreature() || type.isOnTop || type.isOnBottom || type.isGroundClip || type.isGround) + if(thing->asCreature() || type.properties[ThingType::IsOnTop] || type.properties[ThingType::IsOnBottom] || type.properties[ThingType::IsGroundBorder] || type.properties[ThingType::IsGround]) break; thing->draw(p - m_drawElevation); - m_drawElevation += type.elevation; + m_drawElevation += type.parameters[ThingType::Elevation]; if(m_drawElevation > MAX_DRAW_ELEVATION) m_drawElevation = MAX_DRAW_ELEVATION; } @@ -68,8 +68,8 @@ void Tile::draw(const Point& p) for(int xi = -1; xi <= 1; ++xi) { for(int yi = -1; yi <= 1; ++yi) { for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) { - auto& type = creature->getType(); - Rect creatureRect(p.x + xi*32 + creature->getWalkOffset().x - type.xDisplacement, p.y + yi*32 + creature->getWalkOffset().y - type.yDisplacement, 32, 32); + const ThingType& type = creature->getType(); + Rect creatureRect(p.x + xi*32 + creature->getWalkOffset().x - type.parameters[ThingType::DisplacementX], p.y + yi*32 + creature->getWalkOffset().y - type.parameters[ThingType::DisplacementY], 32, 32); Rect thisTileRect(p.x, p.y, 32, 32); // only render creatures where bottom right is inside our rect @@ -87,7 +87,7 @@ void Tile::draw(const Point& p) // top items for(const ThingPtr& thing : m_things) { const ThingType& type = thing->getType(); - if(type.isOnTop) + if(type.properties[ThingType::IsOnTop]) thing->draw(p); } } @@ -180,7 +180,7 @@ ItemPtr Tile::getGround() if(!firstObject) return nullptr; const ThingType& type = firstObject->getType(); - if(type.isGround) + if(type.properties[ThingType::IsGround]) return firstObject->asItem(); return nullptr; } @@ -192,7 +192,7 @@ bool Tile::isWalkable() for(const ThingPtr& thing : m_things) { const ThingType& type = thing->getType(); - if(type.isNotWalkable) + if(type.properties[ThingType::NotWalkable]) return false; } return true; @@ -204,7 +204,7 @@ bool Tile::isFullGround() if(!ground) return false; const ThingType& type = ground->getType(); - if(type.isGround && type.isFullGround) + if(type.properties[ThingType::IsGround] && type.properties[ThingType::IsFullGround]) return true; return false; } @@ -214,7 +214,7 @@ bool Tile::isFullyOpaque() ThingPtr firstObject = getThing(0); if(firstObject) { const ThingType& type = firstObject->getType(); - if(type.isFullGround) + if(type.properties[ThingType::IsFullGround]) return true; } return false; @@ -224,7 +224,7 @@ bool Tile::isLookPossible() { for(const ThingPtr& thing : m_things) { const ThingType& type = thing->getType(); - if(type.isUnsight) + if(type.properties[ThingType::BlockProjectile]) return false; } return true; diff --git a/src/otclient/net/protocolgame.h b/src/otclient/net/protocolgame.h index 6083d2b8..e222563a 100644 --- a/src/otclient/net/protocolgame.h +++ b/src/otclient/net/protocolgame.h @@ -96,7 +96,7 @@ private: void parseWorldLight(InputMessage& msg); void parseMagicEffect(InputMessage& msg); void parseAnimatedText(InputMessage& msg); - void parseDistanceShot(InputMessage& msg); + void parseDistanceMissile(InputMessage& msg); void parseCreatureSquare(InputMessage& msg); void parseCreatureHealth(InputMessage& msg); void parseCreatureLight(InputMessage& msg); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 5b77b8c4..ea241040 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -140,7 +140,7 @@ void ProtocolGame::parseMessage(InputMessage& msg) parseAnimatedText(msg); break; case Otc::GameServerMissleEffect: - parseDistanceShot(msg); + parseDistanceMissile(msg); break; case Otc::GameServerMarkCreature: parseCreatureSquare(msg); @@ -532,7 +532,7 @@ void ProtocolGame::parseAnimatedText(InputMessage& msg) msg.getString(); // text } -void ProtocolGame::parseDistanceShot(InputMessage& msg) +void ProtocolGame::parseDistanceMissile(InputMessage& msg) { Position fromPos = parsePosition(msg); Position toPos = parsePosition(msg); @@ -1057,8 +1057,8 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id) id = msg.getU16(); item->setId(id); - const ThingType& itemType = g_thingsType.getItemType(id); - if(itemType.isStackable || itemType.isFluidContainer || itemType.isSplash) + const ThingType& itemType = item->getType(); + if(itemType.properties[ThingType::IsStackable] || itemType.properties[ThingType::IsFluidContainer] || itemType.properties[ThingType::IsFluid]) item->setData(msg.getU8()); return item;