From 0b4d7ace053872682efedf8c83142d70a90aa0b7 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 31 Aug 2011 17:22:57 -0300 Subject: [PATCH] change how tile stack works --- src/otclient/const.h | 9 +- src/otclient/core/creature.cpp | 14 +- src/otclient/core/effect.cpp | 9 +- src/otclient/core/item.cpp | 2 +- src/otclient/core/map.cpp | 68 ++++--- src/otclient/core/map.h | 13 +- src/otclient/core/thing.cpp | 19 +- src/otclient/core/thing.h | 5 +- src/otclient/core/thingstype.cpp | 10 +- src/otclient/core/thingtype.h | 12 +- src/otclient/core/tile.cpp | 267 +++++++++---------------- src/otclient/core/tile.h | 34 ++-- src/otclient/net/protocolgameparse.cpp | 52 +++-- 13 files changed, 227 insertions(+), 287 deletions(-) diff --git a/src/otclient/const.h b/src/otclient/const.h index d9349aa3..383b3263 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -85,7 +85,7 @@ namespace Otc DatLensHelp = 29, DatFullGround = 30, DatIgnoreLook = 31, - DatClothe = 32, + DatCloth = 32, DatAnimation = 33, DatLastOpt = 255 }; @@ -249,13 +249,6 @@ namespace Otc ClientGetObjectInfo = 243 }; - enum ThingType { - Item, - Creature, - Effect, - Shot - }; - enum SpriteMask { SpriteRedMask = 0, SpriteGreenMask, diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index b8f89323..adf9b09c 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -24,11 +24,14 @@ #include "thingstype.h" #include "localplayer.h" #include "map.h" +#include "tile.h" +#include "item.h" + #include #include -Creature::Creature() : Thing(Otc::Creature) +Creature::Creature() : Thing() { m_healthPercent = 0; m_direction = Otc::South; @@ -218,9 +221,10 @@ void Creature::walk(const Position& position) } // update map tiles - g_map.removeThingByPtr(asThing()); - m_position = position; - g_map.addThing(asThing()); + TilePtr oldTile = g_map.getTile(m_position); + TilePtr newTile = g_map.getTile(position); + oldTile->removeThing(asThing()); + newTile->addThing(asThing(), -1); if(m_walking) { // Calculate xPattern @@ -237,7 +241,7 @@ void Creature::walk(const Position& position) // get walk speed int groundSpeed = 0; - ThingPtr ground = g_map.getThing(m_position, 0); + ItemPtr ground = newTile->getGround(); if(ground) groundSpeed = ground->getType().groundSpeed; diff --git a/src/otclient/core/effect.cpp b/src/otclient/core/effect.cpp index b3a6db85..46a6c93a 100644 --- a/src/otclient/core/effect.cpp +++ b/src/otclient/core/effect.cpp @@ -23,10 +23,11 @@ #include "effect.h" #include "thingstype.h" #include "map.h" +#include "tile.h" #include #include -Effect::Effect() : Thing(Otc::Effect) +Effect::Effect() : Thing() { m_lastTicks = g_platform.getTicks(); m_finished = false; @@ -38,7 +39,11 @@ void Effect::draw(int x, int y) if(g_platform.getTicks() - m_lastTicks > 75) { const ThingType& type = getType(); if(m_animation+1 == type.animationPhases) { - g_dispatcher.addEvent(std::bind(&Map::removeThingByPtr, &g_map, asThing())); + EffectPtr self = asEffect(); + g_dispatcher.addEvent([self] { + TilePtr tile = g_map.getTile(self->getPosition()); + tile->removeEffect(self); + }); m_finished = true; } else diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index a2279487..d44f53bc 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -26,7 +26,7 @@ #include "thing.h" #include -Item::Item() : Thing(Otc::Item) +Item::Item() : Thing() { m_count = 0; m_lastTicks = g_platform.getTicks(); diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index b22215b4..756d761d 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -76,18 +76,16 @@ void Map::draw(const Rect& rect) // draw player names and health bars for(int x = 0; x < MAP_VISIBLE_WIDTH; ++x) { for(int y = 0; y < MAP_VISIBLE_HEIGHT; ++y) { - Position tilePos = Position(m_centralPosition.x + (x - PLAYER_OFFSET_X - 1), m_centralPosition.y + (y - PLAYER_OFFSET_Y - 1), m_centralPosition.z); + Position tilePos = Position(m_centralPosition.x + (x - PLAYER_OFFSET_X + 1), m_centralPosition.y + (y - PLAYER_OFFSET_Y + 1), m_centralPosition.z); if(const TilePtr& tile = m_tiles[tilePos]) { - auto& creatures = tile->getCreatures(); + auto creatures = tile->getCreatures(); if(creatures.size() == 0) continue; - for(auto it = creatures.rbegin(), end = creatures.rend(); it != end; ++it) { - CreaturePtr creature = (*it)->asCreature(); - - int x = (7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawNextOffset(); - int y = (5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawNextOffset(); + for(const CreaturePtr& creature : creatures) { + int x = (7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(); + int y = (5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation(); if(creature != localPlayer) { x += creature->getWalkOffsetX() - walkOffsetX; @@ -101,6 +99,11 @@ void Map::draw(const Rect& rect) } } +void Map::clean() +{ + m_tiles.clear(); +} + int Map::getMaxVisibleFloor() { Position tilePos = m_centralPosition; @@ -159,7 +162,7 @@ bool Map::isCompletlyCovered(const Position& pos, int maxFloor) for(int x=0;x<2;++x) { for(int y=0;y<2;++y) { TilePtr tile = m_tiles[tilePos + Position(-x, -y, 0)]; - if(!tile || !tile->isOpaque()) { + if(!tile || !tile->isFullyOpaque()) { covered = false; break; } @@ -172,50 +175,46 @@ bool Map::isCompletlyCovered(const Position& pos, int maxFloor) return false; } -void Map::addThing(ThingPtr thing, int stackpos) +void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos) { if(!thing) return; - TilePtr& tile = m_tiles[thing->getPosition()]; - if(!tile) { - tile = TilePtr(new Tile(thing->getPosition())); - } - - tile->addThing(thing, stackpos); + TilePtr tile = getTile(pos); + tile->addThing(thing, stackPos); - if(const CreaturePtr& creature = thing->asCreature()) - m_creatures[thing->getId()] = creature; + if(CreaturePtr creature = thing->asCreature()) + m_creatures[creature ->getId()] = creature; } -ThingPtr Map::getThing(const Position& pos, int stackpos) +ThingPtr Map::getThing(const Position& pos, int stackPos) { - if(const TilePtr& tile = m_tiles[pos]) { - return tile->getThing(stackpos); - } - return ThingPtr(); + if(const TilePtr& tile = m_tiles[pos]) + return tile->getThing(stackPos); + return nullptr; } -void Map::removeThing(const Position& pos, int stackpos) +void Map::removeThing(const Position& pos, int stackPos) { - if(TilePtr& tile = m_tiles[pos]) { - tile->removeThing(stackpos); - } + if(TilePtr& tile = m_tiles[pos]) + tile->removeThing(stackPos); } -void Map::removeThingByPtr(ThingPtr thing) +void Map::removeThing(const ThingPtr& thing) { if(!thing) return; - if(TilePtr& tile = m_tiles[thing->getPosition()]) { - tile->removeThingByPtr(thing); - } + if(TilePtr& tile = m_tiles[thing->getPosition()]) + tile->removeThing(thing); } -void Map::clean() +TilePtr Map::getTile(const Position& pos) { - m_tiles.clear(); + TilePtr& tile = m_tiles[pos]; + if(!tile) + tile = TilePtr(new Tile(pos)); + return tile; } void Map::cleanTile(const Position& pos) @@ -224,6 +223,11 @@ void Map::cleanTile(const Position& pos) tile->clean(); } +void Map::addCreature(const CreaturePtr& creature) +{ + m_creatures[creature->getId()] = creature; +} + CreaturePtr Map::getCreatureById(uint32 id) { if(g_game.getLocalPlayer() && g_game.getLocalPlayer()->getId() == id) diff --git a/src/otclient/core/map.h b/src/otclient/core/map.h index 6b766ee1..f3cbd680 100644 --- a/src/otclient/core/map.h +++ b/src/otclient/core/map.h @@ -42,18 +42,18 @@ class Map public: void draw(const Rect& rect); + void clean(); int getMaxVisibleFloor(); bool isCovered(const Position& pos, int maxFloor); bool isCompletlyCovered(const Position& pos, int maxFloor); - void addThing(ThingPtr thing, int stackpos = -1); - ThingPtr getThing(const Position& pos, int stackpos); - void removeThing(const Position& pos, int stackpos); - void removeThingByPtr(ThingPtr thing); - - void clean(); + void addThing(const ThingPtr& thing, const Position& pos, int stackPos = -1); + ThingPtr getThing(const Position& pos, int stackPos); + void removeThing(const Position& pos, int stackPos); + void removeThing(const ThingPtr& thing); void cleanTile(const Position& pos); + TilePtr getTile(const Position& pos); void setLight(const Light& light) { m_light = light; } Light getLight() { return m_light; } @@ -61,6 +61,7 @@ public: void setCentralPosition(const Position& centralPosition); Position getCentralPosition() { return m_centralPosition; } + void addCreature(const CreaturePtr& creature); CreaturePtr getCreatureById(uint32 id); void removeCreatureById(uint32 id); diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index 74d63405..f97a7811 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -24,7 +24,7 @@ #include "spritemanager.h" #include -Thing::Thing(Otc::ThingType type) : m_id(0), m_type(type) +Thing::Thing() : m_id(0) { m_xPattern = 0; m_yPattern = 0; @@ -67,3 +67,20 @@ void Thing::internalDraw(int x, int y, int layers, Otc::SpriteMask mask) } } } + +int Thing::getStackPriority() +{ + const ThingType& type = getType(); + if(type.isGround) + return 0; + else if(type.isGroundClip) + return 1; + else if(type.isOnBottom) + return 2; + else if(type.isOnTop) + return 3; + else if(asCreature()) + return 4; + return 5; +} + diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index e94b6b99..8da0f1ce 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -36,7 +36,7 @@ struct Light class Thing : public LuaObject { public: - Thing(Otc::ThingType type); + Thing(); virtual ~Thing() { } virtual void draw(int x, int y) = 0; @@ -45,8 +45,8 @@ public: void setPosition(const Position& position); uint32 getId() const { return m_id; } - Otc::ThingType getType() const { return m_type; } Position getPosition() const { return m_position; } + int getStackPriority(); virtual const ThingType& getType() = 0; virtual void onPositionChange(const Position&) {} @@ -62,7 +62,6 @@ protected: void internalDraw(int x, int y, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask); uint32 m_id; - Otc::ThingType m_type; Position m_position; int m_xPattern, m_yPattern, m_zPattern, m_animation; diff --git a/src/otclient/core/thingstype.cpp b/src/otclient/core/thingstype.cpp index 493b025a..a250bf89 100644 --- a/src/otclient/core/thingstype.cpp +++ b/src/otclient/core/thingstype.cpp @@ -174,7 +174,7 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType) break; case Otc::DatLensHelp: // Used for giving players tips? thingType.isLensHelp = true; - thingType.lensHelpParam = Fw::getU16(fin); + thingType.lensHelp = Fw::getU16(fin); break; case Otc::DatFullGround: // Grounds that has no transparent pixels thingType.isFullGround = true; @@ -182,9 +182,9 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType) case Otc::DatIgnoreLook: // Ignore look, then looks at the item on the bottom of it thingType.isIgnoreLook = true; break; - case Otc::DatClothe: // Clothes - break; - case Otc::DatAnimation: // Not used in 8.62 + case Otc::DatCloth: // Clothes + thingType.isCloth = true; + thingType.clothSlot = Fw::getU16(fin); break; case Otc::DatLastOpt: done = true; @@ -207,6 +207,8 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType) 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 diff --git a/src/otclient/core/thingtype.h b/src/otclient/core/thingtype.h index aa4d94f4..748eb309 100644 --- a/src/otclient/core/thingtype.h +++ b/src/otclient/core/thingtype.h @@ -64,7 +64,8 @@ struct ThingType isLensHelp = false; isFullGround = false; isIgnoreLook = false; - isClothe = false; + isCloth = false; + isAnimation = false; hasLight = false; hasMiniMapColor = false; @@ -73,7 +74,8 @@ struct ThingType maxTextLength = 0; lightLevel = lightColor = 0; miniMapColor = 0; - lensHelpParam = 0; + lensHelp = 0; + clothSlot = 0; } uint8 layers; @@ -113,7 +115,8 @@ struct ThingType bool isLensHelp; bool isFullGround; bool isIgnoreLook; - bool isClothe; + bool isCloth; + bool isAnimation; bool hasLight; bool hasMiniMapColor; @@ -122,7 +125,8 @@ struct ThingType uint16 maxTextLength; uint16 lightLevel, lightColor; uint16 miniMapColor; - uint16 lensHelpParam; + uint16 lensHelp; + uint16 clothSlot; }; typedef std::vector ThingTypeList; diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index c5f4d94d..2e236e7d 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -26,221 +26,146 @@ #include "map.h" #include "game.h" #include "localplayer.h" +#include "effect.h" #include Tile::Tile(const Position& position) { - m_drawNextOffset = 0; + m_drawElevation = 0; m_position = position; } void Tile::draw(int x, int y) { - m_drawNextOffset = 0; + m_drawElevation = 0; - if(m_ground) - m_ground->draw(x, y); - - for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - const ThingType& thingType = thing->getType(); - - if(thingType.isGroundClip) { - thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); - m_drawNextOffset += thingType.elevation; - } + // first bottom items + for(const ThingPtr& thing : m_things) { + const ThingType& type = thing->getType(); + if(thing->asCreature() || type.isOnTop) + continue; + thing->draw(x - m_drawElevation, y - m_drawElevation); + m_drawElevation += type.elevation; } - for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - const ThingType& thingType = thing->getType(); - - if(thingType.isOnBottom) { - thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); - m_drawNextOffset += thingType.elevation; - } + // creatures + for(const ThingPtr& thing : m_things) { + if(thing->asCreature()) + thing->draw(x - m_drawElevation, y - m_drawElevation); } - for(auto it = m_itemsBottom.rbegin(), end = m_itemsBottom.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - const ThingType& thingType = thing->getType(); - thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); - m_drawNextOffset += thingType.elevation; - } + // effects + for(const EffectPtr& effect : m_effects) + effect->draw(x - m_drawElevation, y - m_drawElevation); - for(auto it = m_creatures.rbegin(), end = m_creatures.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); + // top items + for(const ThingPtr& thing : m_things) { + const ThingType& type = thing->getType(); + if(type.isOnTop) + thing->draw(x - m_drawElevation, y - m_drawElevation); } +} - for(auto it = m_effects.rbegin(), end = m_effects.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); - } +void Tile::clean() +{ + m_things.clear(); + m_effects.clear(); +} - for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) { - const ThingPtr& thing = *it; - const ThingType& thingType = thing->getType(); +void Tile::addEffect(const EffectPtr& effect) +{ + m_effects.push_back(effect); + effect->setPosition(m_position); +} - if(thingType.isOnTop) { - thing->draw(x, y); - } +void Tile::removeEffect(const EffectPtr& effect) +{ + auto it = std::find(m_effects.begin(), m_effects.end(), effect); + if(it != m_effects.end()) { + m_effects.erase(it); } } -void Tile::addThing(ThingPtr thing, int stackpos) +ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos) { - // TODO: rework this. that -1 sucks if(!thing) - return; - - const ThingType& thingType = thing->getType(); - - if(thing->asItem()) { - if(thingType.isGround) - m_ground = thing; - else { - if(thingType.isGroundClip || thingType.isOnBottom || thingType.isOnTop) - m_itemsTop.push_back(thing); - else { - if(stackpos == -1) - m_itemsBottom.push_back(thing); - else { - m_itemsBottom.insert(m_itemsBottom.begin()+(stackpos-getStackSize(2)), thing); - } - } + return nullptr; + + if(stackPos < 0) { + stackPos = 0; + int priority = thing->getStackPriority(); + for(stackPos = 0; stackPos < (int)m_things.size(); ++stackPos) { + int otherPriority = m_things[stackPos]->getStackPriority(); + if(otherPriority > priority || (otherPriority == priority && otherPriority == 5)) + break; } - } - else if(thing->asCreature()) { - m_creatures.push_back(thing); - } - else if(thing->asEffect()) { - m_effects.push_back(thing); - } + } else if(stackPos > (int)m_things.size()) + stackPos = m_things.size(); + + ThingPtr oldObject; + if(stackPos < (int)m_things.size()) + oldObject = m_things[stackPos]; + m_things.insert(m_things.begin() + stackPos, thing); + thing->setPosition(m_position); + return oldObject; } -ThingPtr Tile::getThing(unsigned int stackpos) +ThingPtr Tile::getThing(int stackPos) { - if(stackpos == 0) - return m_ground; - --stackpos; - - if(stackpos < m_itemsTop.size()) - return m_itemsTop[stackpos]; - stackpos -= m_itemsTop.size(); - - if(stackpos < m_creatures.size()) - return m_creatures[stackpos]; - stackpos -= m_creatures.size(); - - if(stackpos < m_itemsBottom.size()) - return m_itemsBottom[stackpos]; - - return ThingPtr(); + if(stackPos >= 0 && stackPos < (int)m_things.size()) + return m_things[stackPos]; + return nullptr; } -void Tile::removeThing(unsigned int stackpos) +ThingPtr Tile::removeThing(int stackPos) { - if(stackpos == 0) { - m_ground.reset(); - return; + ThingPtr oldObject; + if(stackPos >= 0 && stackPos < (int)m_things.size()) { + oldObject = m_things[stackPos]; + m_things.erase(m_things.begin() + stackPos); } - --stackpos; - - if(stackpos < m_itemsTop.size()) { - m_itemsTop.erase(m_itemsTop.begin() + stackpos); - return; - } - stackpos -= m_itemsTop.size(); - - if(stackpos < m_creatures.size()) { - m_creatures.erase(m_creatures.begin() + stackpos); - return; - } - stackpos -= m_creatures.size(); - - if(stackpos < m_itemsBottom.size()) { - m_itemsBottom.erase(m_itemsBottom.begin() + stackpos); - return; - } - - logDebug("Invalid stackpos."); + return oldObject; } -void Tile::removeThingByPtr(ThingPtr thing) +ThingPtr Tile::removeThing(const ThingPtr& thing) { - // Items - if(thing->asItem()) { - const ThingType& thingType = thing->getType(); - - if(!(thingType.isGroundClip || thingType.isOnBottom || thingType.isOnTop)) { - for(auto it = m_itemsBottom.begin(), end = m_itemsBottom.end(); it != end; ++it) { - if(*it == thing) { - m_itemsBottom.erase(it); - break; - } - } - } - else { - for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it) { - if(*it == thing) { - m_itemsTop.erase(it); - break; - } - } - } - } - - // Creatures - else if(thing->asCreature()) { - for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it) { - if(*it == thing) { - m_creatures.erase(it); - break; - } - } - } - - // Effects - else if(thing->asEffect()) { - for(auto it = m_effects.begin(), end = m_effects.end(); it != end; ++it) { - if(*it == thing) { - m_effects.erase(it); - break; - } - } + ThingPtr oldObject; + auto it = std::find(m_things.begin(), m_things.end(), thing); + if(it != m_things.end()) { + oldObject = *it; + m_things.erase(it); } + return oldObject; } -void Tile::clean() +std::vector Tile::getCreatures() { - m_itemsTop.clear(); - m_creatures.clear(); - m_itemsBottom.clear(); - m_effects.clear(); + std::vector creatures; + for(const ThingPtr& thing : m_things) { + if(CreaturePtr creature = thing->asCreature()) + creatures.push_back(creature); + } + return creatures; } -int Tile::getStackSize(int stop) +ItemPtr Tile::getGround() { - int ret = m_ground ? 1 : 0; - if(stop == 0) - return ret; - - ret += m_itemsTop.size(); - if(stop == 1) - return ret; - - ret += m_creatures.size(); - if(stop == 2) - return ret; - - ret += m_itemsBottom.size(); - return ret; + ThingPtr firstObject = getThing(0); + if(!firstObject) + return nullptr; + const ThingType& type = firstObject->getType(); + if(type.isGround) + return firstObject->asItem(); + return nullptr; } -bool Tile::isOpaque() +bool Tile::isFullyOpaque() { - if(m_ground && !m_ground->getType().isTranslucent) - return true; + ThingPtr firstObject = getThing(0); + if(firstObject) { + const ThingType& type = firstObject->getType(); + if(type.isGround && !type.isTranslucent) + return true; + } return false; } diff --git a/src/otclient/core/tile.h b/src/otclient/core/tile.h index b96d1cdc..b7056ef2 100644 --- a/src/otclient/core/tile.h +++ b/src/otclient/core/tile.h @@ -32,34 +32,26 @@ public: Tile(const Position& position); void draw(int x, int y); - - void addThing(ThingPtr thing, int stackpos); - ThingPtr getThing(unsigned int stackpos); - void removeThing(unsigned int stackpos); - void removeThingByPtr(ThingPtr thing); - void clean(); - bool hasGround() { return (!!m_ground); } - - int getStackSize(int stop); - - const ThingList& getCreatures() { return m_creatures; } - int getDrawNextOffset() { return m_drawNextOffset; } + void addEffect(const EffectPtr& effect); + void removeEffect(const EffectPtr& effect); + ThingPtr addThing(const ThingPtr& thing, int stackPos = -1); + ThingPtr getThing(int stackPos); + ThingPtr removeThing(int stackPos); + ThingPtr removeThing(const ThingPtr& thing); const Position& getPosition() { return m_position; } - - bool isOpaque(); + int getDrawElevation() { return m_drawElevation; } + std::vector getCreatures(); + ItemPtr getGround(); + bool isFullyOpaque(); private: - ThingPtr m_ground; - ThingList m_itemsBottom; - ThingList m_creatures; - ThingList m_itemsTop; - ThingList m_effects; + std::vector m_effects; + std::vector m_things; Position m_position; - - int m_drawNextOffset; + int m_drawElevation; }; #endif diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 9057e918..d4284de8 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include void ProtocolGame::parseMessage(InputMessage& msg) @@ -364,18 +365,16 @@ void ProtocolGame::parseUpdateTile(InputMessage& msg) void ProtocolGame::parseTileAddThing(InputMessage& msg) { Position pos = parsePosition(msg); - uint8 stackpos = msg.getU8(); + uint8 stackPos = msg.getU8(); ThingPtr thing = internalGetThing(msg); - thing->setPosition(pos); - - g_map.addThing(thing, stackpos); + g_map.addThing(thing, pos, stackPos); } void ProtocolGame::parseTileTransformThing(InputMessage& msg) { Position pos = parsePosition(msg); - uint8 stackpos = msg.getU8(); + uint8 stackPos = msg.getU8(); uint16 thingId = msg.getU16(); if(thingId == 0x0061 || thingId == 0x0062 || thingId == 0x0063) { @@ -383,19 +382,17 @@ void ProtocolGame::parseTileTransformThing(InputMessage& msg) } else { ThingPtr thing = internalGetItem(msg, thingId); - thing->setPosition(pos); - - g_map.removeThing(pos, stackpos); - g_map.addThing(thing, stackpos); + g_map.removeThing(pos, stackPos); + g_map.addThing(thing, pos, stackPos); } } void ProtocolGame::parseTileRemoveThing(InputMessage& msg) { Position pos = parsePosition(msg); - uint8 stackpos = msg.getU8(); + uint8 stackPos = msg.getU8(); - g_map.removeThing(pos, stackpos); + g_map.removeThing(pos, stackPos); } void ProtocolGame::parseCreatureMove(InputMessage& msg) @@ -404,12 +401,11 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg) uint8 oldStackpos = msg.getU8(); Position newPos = parsePosition(msg); - ThingPtr thing = g_map.getThing(oldPos, oldStackpos); - if(thing) { - CreaturePtr creature = thing->asCreature(); - if(creature) - creature->walk(newPos); - } + ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos); + assert(thing); + CreaturePtr creature = thing->asCreature(); + assert(creature); + creature->walk(newPos); } void ProtocolGame::parseOpenContainer(InputMessage& msg) @@ -512,11 +508,13 @@ void ProtocolGame::parseWorldLight(InputMessage& msg) void ProtocolGame::parseMagicEffect(InputMessage& msg) { + Position pos = parsePosition(msg); + int effectId = msg.getU8(); EffectPtr effect = EffectPtr(new Effect()); - effect->setPosition(parsePosition(msg)); - effect->setId(msg.getU8()); + effect->setId(effectId); - g_map.addThing(effect); + TilePtr tile = g_map.getTile(pos); + tile->addEffect(effect); } void ProtocolGame::parseAnimatedText(InputMessage& msg) @@ -895,23 +893,19 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position) { g_map.cleanTile(position); - int stackpos = 0; + int stackPos = 0; while(1){ uint16 inspectTileId = msg.getU16(true); if(inspectTileId >= 0xFF00) return; else { - if(stackpos >= 10) { - logTraceDebug("Too many things!."); - return; - } + if(stackPos >= 10) + logWarning("Too many things!"); ThingPtr thing = internalGetThing(msg); - if(thing) - thing->setPosition(position); - g_map.addThing(thing); + g_map.addThing(thing, position); } - stackpos++; + stackPos++; } }