From daea7cab6534f9bc9976f458f1915c391065774c Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 1 Aug 2012 22:33:56 -0300 Subject: [PATCH] Check walk collisions in client side --- src/otclient/game.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/otclient/item.cpp | 5 ++++- src/otclient/tile.cpp | 9 +++++++++ src/otclient/tile.h | 1 + 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/otclient/game.cpp b/src/otclient/game.cpp index e0b038e3..ea915365 100644 --- a/src/otclient/game.cpp +++ b/src/otclient/game.cpp @@ -489,12 +489,44 @@ void Game::walk(Otc::Direction direction) if(!m_localPlayer->canWalk(direction)) return; + Position toPos = m_localPlayer->getPosition().translatedToDirection(direction); + TilePtr toTile = g_map.getTile(toPos); // only do prewalks to walkable tiles (like grounds and not walls) - TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction)); if(toTile && toTile->isWalkable()) m_localPlayer->preWalk(direction); - else - m_localPlayer->lockWalk(100); + // check walk to another floor (e.g: when above 3 parcels) + else { + // check if can walk to a lower floor + auto canChangeFloorDown = [&] { + Position pos = toPos; + if(!pos.down()) + return false; + toTile = g_map.getTile(pos); + if(toTile && toTile->hasElevation(3)) { + return true; + } + return false; + }; + + // check if can walk to a higher floor + auto canChangeFloorUp = [&] { + TilePtr fromTile = m_localPlayer->getTile(); + if(!fromTile || !fromTile->hasElevation(3)) + return false; + Position pos = toPos; + if(!pos.up()) + return false; + toTile = g_map.getTile(pos); + if(!toTile || !toTile->isWalkable()) + return false; + return true; + }; + + if(canChangeFloorDown() || canChangeFloorUp()) { + m_localPlayer->lockWalk(); + } else + return; + } forceWalk(direction); diff --git a/src/otclient/item.cpp b/src/otclient/item.cpp index 8485543b..03122998 100644 --- a/src/otclient/item.cpp +++ b/src/otclient/item.cpp @@ -29,6 +29,7 @@ #include "container.h" #include "map.h" #include "houses.h" +#include "game.h" #include #include @@ -302,7 +303,9 @@ int Item::getSubType() { if(isSplash() || isFluidContainer()) return m_countOrSubType; - return 0; + if(g_game.getClientVersion() >= 900) + return 0; + return 1; } int Item::getCount() diff --git a/src/otclient/tile.cpp b/src/otclient/tile.cpp index 0048eefe..9ee35983 100644 --- a/src/otclient/tile.cpp +++ b/src/otclient/tile.cpp @@ -513,3 +513,12 @@ bool Tile::canErase() { return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty(); } + +bool Tile::hasElevation(int elevation) +{ + int count = 0; + for(const ThingPtr& thing : m_things) + if(thing->getElevation() > 0) + count++; + return count >= elevation; +} diff --git a/src/otclient/tile.h b/src/otclient/tile.h index bfcbf161..fd84f0e9 100644 --- a/src/otclient/tile.h +++ b/src/otclient/tile.h @@ -102,6 +102,7 @@ public: bool hasCreature(); bool limitsFloorsView(); bool canErase(); + bool hasElevation(int elevation = 1); void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; } uint32 getFlags() { return m_flags; }