diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 5b8b70e5..59c37330 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -69,12 +69,12 @@ void Creature::draw(const Point& dest, float scaleFactor) if(m_showVolatileSquare) { g_painter.setColor(m_volatileSquareColor); - g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 3)*scaleFactor, Size(28*scaleFactor, 28*scaleFactor)), 2*scaleFactor); + g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 3)*scaleFactor, Size(28*scaleFactor, 28*scaleFactor)), std::max((int)(2*scaleFactor), 1)); } if(m_showStaticSquare) { g_painter.setColor(m_staticSquareColor); - g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), 2*scaleFactor); + g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), std::max((int)(2*scaleFactor), 1)); } g_painter.setColor(Fw::white); @@ -134,10 +134,10 @@ void Creature::draw(const Point& dest, float scaleFactor) } else if(m_outfit.getCategory() == ThingsType::Item) { for(int l = 0; l < getLayers(); l++) - internalDraw(dest + m_walkOffset * scaleFactor, scaleFactor, l); + internalDraw(dest + m_walkOffset, scaleFactor, l); } else if(m_outfit.getCategory() == ThingsType::Effect) - internalDraw(dest + m_walkOffset * scaleFactor, scaleFactor, 0); + internalDraw(dest + m_walkOffset, scaleFactor, 0); } void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect) @@ -276,6 +276,36 @@ void Creature::updateWalkOffset(int totalPixelsWalked) m_walkOffset.x = 32 - totalPixelsWalked; } +void Creature::updateWalkingTile() +{ + // determine new walking tile + TilePtr newWalkingTile; + Rect virtualCreatureRect(Otc::TILE_PIXELS + (m_walkOffset.x - getDisplacementX()), + Otc::TILE_PIXELS + (m_walkOffset.y - getDisplacementY()), + Otc::TILE_PIXELS, Otc::TILE_PIXELS); + for(int xi = -1; xi <= 1 && !newWalkingTile; ++xi) { + for(int yi = -1; yi <= 1 && !newWalkingTile; ++yi) { + Rect virtualTileRect((xi+1)*Otc::TILE_PIXELS, (yi+1)*Otc::TILE_PIXELS, Otc::TILE_PIXELS, Otc::TILE_PIXELS); + + // only render creatures where bottom right is inside tile rect + if(virtualTileRect.contains(virtualCreatureRect.bottomRight())) { + const TilePtr& tile = g_map.getTile(m_position.translated(xi, yi, 0)); + if(!tile) + continue; + newWalkingTile = tile; + } + } + } + + if(newWalkingTile != m_walkingTile) { + if(m_walkingTile) + m_walkingTile->removeWalkingCreature(asCreature()); + if(newWalkingTile) + newWalkingTile->addWalkingCreature(asCreature()); + m_walkingTile = newWalkingTile; + } +} + void Creature::nextWalkUpdate() { // remove any previous scheduled walk updates @@ -303,6 +333,7 @@ void Creature::updateWalk() // update walk animation and offsets updateWalkAnimation(totalPixelsWalked); updateWalkOffset(totalPixelsWalked); + updateWalkingTile(); // terminate walk if(m_walking && m_walkTimer.ticksElapsed() >= m_walkInterval) @@ -323,6 +354,11 @@ void Creature::terminateWalk() m_walkTurnDirection = Otc::InvalidDirection; } + if(m_walkingTile) { + m_walkingTile->removeWalkingCreature(asCreature()); + m_walkingTile = nullptr; + } + m_walking = false; } diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index 250d53c6..e85db78e 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -78,8 +78,6 @@ public: void updateInvisibleAnimation(); void updateShield(); - ThingType *getType(); - // walk related void turn(Otc::Direction direction); virtual void walk(const Position& oldPos, const Position& newPos); @@ -93,6 +91,7 @@ public: protected: virtual void updateWalkAnimation(int totalPixelsWalked); virtual void updateWalkOffset(int totalPixelsWalked); + void updateWalkingTile(); virtual void nextWalkUpdate(); virtual void updateWalk(); virtual void terminateWalk(); @@ -116,6 +115,7 @@ protected: // walk related Timer m_walkTimer; + TilePtr m_walkingTile; int m_walkInterval; int m_walkAnimationInterval; bool m_walking; diff --git a/src/otclient/core/localplayer.cpp b/src/otclient/core/localplayer.cpp index 9c98ecc4..6a5b25a9 100644 --- a/src/otclient/core/localplayer.cpp +++ b/src/otclient/core/localplayer.cpp @@ -145,6 +145,7 @@ void LocalPlayer::updateWalk() // update walk animation and offsets updateWalkAnimation(totalPixelsWalked); updateWalkOffset(totalPixelsWalked); + updateWalkingTile(); // terminate walk only when client and server side walk are complated if(m_walking && !m_preWalking && m_walkTimer.ticksElapsed() >= m_walkInterval) diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index e23016a6..4a42c262 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -304,7 +304,7 @@ std::vector Map::getSpectatorsInRangeEx(const Position& centerPos, continue; auto tileCreatures = tile->getCreatures(); - creatures.insert(creatures.end(), tileCreatures.begin(), tileCreatures.end()); + creatures.insert(creatures.end(), tileCreatures.rbegin(), tileCreatures.rend()); } } } @@ -376,7 +376,7 @@ bool Map::isAwareOfPosition(const Position& pos) int Map::getFirstAwareFloor() { if(m_centralPosition.z > Otc::SEA_FLOOR) - return m_centralPosition.z-2; + return m_centralPosition.z-Otc::AWARE_UNDEGROUND_FLOOR_RANGE; else return 0; } @@ -384,7 +384,7 @@ int Map::getFirstAwareFloor() int Map::getLastAwareFloor() { if(m_centralPosition.z > Otc::SEA_FLOOR) - return std::min(m_centralPosition.z+2, (int)Otc::MAX_Z); + return std::min(m_centralPosition.z+Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::MAX_Z); else return Otc::SEA_FLOOR; } diff --git a/src/otclient/core/mapview.cpp b/src/otclient/core/mapview.cpp index 334f795b..338c3157 100644 --- a/src/otclient/core/mapview.cpp +++ b/src/otclient/core/mapview.cpp @@ -45,7 +45,6 @@ MapView::MapView() m_shaderProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); m_shaderProgram->addShaderFromSourceFile(Shader::Fragment, "/game_shaders/map.frag"); assert(m_shaderProgram->link()); - //m_animated = false; } void MapView::draw(const Rect& rect) @@ -60,7 +59,7 @@ void MapView::draw(const Rect& rect) if(isNearView()) tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures | Otc::DrawEffects; else if(isMidView()) - tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems; + tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures; else if(isFarView()) tileDrawFlags = Otc::DrawGround | Otc::DrawWalls; else // huge far view @@ -161,6 +160,10 @@ bool MapView::updateVisibleTilesCache() int firstFloor = getFirstVisibleFloor(); int lastFloor = getLastVisibleFloor(); + + if(lastFloor < firstFloor) + lastFloor = firstFloor; + m_cachedFirstVisibleFloor = firstFloor; m_cachedLastVisibleFloor = lastFloor; Position cameraPosition = getCameraPosition(); @@ -291,7 +294,7 @@ int MapView::getFirstVisibleFloor() // limits to underground floors while under sea level if(cameraPosition.z > Otc::SEA_FLOOR) - firstFloor = Otc::SEA_FLOOR+1; + firstFloor = cameraPosition.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE; // loop in 3x3 tiles around the camera for(int ix = -1; ix <= 1 && firstFloor < cameraPosition.z; ++ix) { @@ -338,7 +341,7 @@ int MapView::getLastVisibleFloor() // view only underground floors when below sea level if(cameraPosition.z > Otc::SEA_FLOOR) - return Otc::MAX_Z; + return cameraPosition.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE; else return Otc::SEA_FLOOR; } diff --git a/src/otclient/core/mapview.h b/src/otclient/core/mapview.h index 1d9ce297..84c5026b 100644 --- a/src/otclient/core/mapview.h +++ b/src/otclient/core/mapview.h @@ -31,9 +31,9 @@ class MapView : public LuaObject { enum { DEFAULT_FRAMBUFFER_SIZE = 2048, - NEAR_VIEW_AREA = 4096, - MID_VIEW_AREA = 16384, - FAR_VIEW_AREA = 32768 + NEAR_VIEW_AREA = 64*64, + MID_VIEW_AREA = 128*128, + FAR_VIEW_AREA = 192*192 }; public: diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index be5e97ad..c8bdfd1b 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -77,6 +77,8 @@ void Thing::internalDraw(const Point& dest, float scaleFactor, int layer) Rect drawRect((dest.x - w*scaledSize) - getDisplacementX()*scaleFactor, (dest.y - h*scaledSize) - getDisplacementY()*scaleFactor, scaledSize, scaledSize); + + g_painter.setColor(Fw::white); g_painter.drawTexturedRect(drawRect, spriteTex); } } diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index 95a9fdc9..963dffd1 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -38,7 +38,7 @@ Tile::Tile(const Position& position) void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) { - m_drawElevation = 0; + int drawElevation = 0; // first bottom items if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawWalls) { @@ -47,11 +47,11 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) break; if((drawFlags & Otc::DrawGround && thing->isGround()) || (drawFlags & Otc::DrawWalls)) - thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor); + thing->draw(dest - drawElevation*scaleFactor, scaleFactor); - m_drawElevation += thing->getElevation(); - if(m_drawElevation > Otc::MAX_ELEVATION) - m_drawElevation = Otc::MAX_ELEVATION; + drawElevation += thing->getElevation(); + if(drawElevation > Otc::MAX_ELEVATION) + drawElevation = Otc::MAX_ELEVATION; } } @@ -59,37 +59,28 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) if(drawFlags & Otc::DrawCommonItems) { for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { const ThingPtr& thing = *it; - if(thing->asCreature() || thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround()) + if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature()) break; - thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor); + thing->draw(dest - drawElevation*scaleFactor, scaleFactor); - m_drawElevation += thing->getElevation(); - if(m_drawElevation > Otc::MAX_ELEVATION) - m_drawElevation = Otc::MAX_ELEVATION; + drawElevation += thing->getElevation(); + if(drawElevation > Otc::MAX_ELEVATION) + drawElevation = Otc::MAX_ELEVATION; } } - // we can render creatures in 3x3 range + // creatures if(drawFlags & Otc::DrawCreatures) { - for(int xi = -1; xi <= 1; ++xi) { - for(int yi = -1; yi <= 1; ++yi) { - const TilePtr& tile = g_map.getTile(m_position.translated(xi, yi, 0)); - if(!tile) - continue; - for(const CreaturePtr& creature : tile->getCreatures()) { - int tileSize = Otc::TILE_PIXELS * scaleFactor; - Rect creatureRect(dest.x + xi*tileSize + (creature->getWalkOffset().x - creature->getDisplacementX())*scaleFactor, - dest.y + yi*tileSize + (creature->getWalkOffset().y - creature->getDisplacementY())*scaleFactor, - tileSize, tileSize); - Rect thisTileRect(dest.x, dest.y, tileSize, tileSize); + for(const CreaturePtr& creature : m_walkingCreatures) { + creature->draw(Point(dest.x + ((creature->getPosition().x - m_position.x)*Otc::TILE_PIXELS - drawElevation)*scaleFactor, + dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - drawElevation)*scaleFactor), scaleFactor); - // only render creatures where bottom right is inside our rect - if(thisTileRect.contains(creatureRect.bottomRight())) { - creature->draw(Point(dest.x + xi*tileSize - m_drawElevation*scaleFactor, - dest.y + yi*tileSize - m_drawElevation*scaleFactor), scaleFactor); - } - } - } + } + + for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { + CreaturePtr creature = (*it)->asCreature(); + if(creature && !creature->isWalking()) + creature->draw(dest - drawElevation, scaleFactor); } } @@ -103,7 +94,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) if(drawFlags & Otc::DrawWalls) { for(const ThingPtr& thing : m_things) { if(thing->isOnTop()) - thing->draw(dest - m_drawElevation, scaleFactor); + thing->draw(dest - drawElevation, scaleFactor); } } } @@ -114,6 +105,18 @@ void Tile::clean() m_effects.clear(); } +void Tile::addWalkingCreature(const CreaturePtr& creature) +{ + m_walkingCreatures.push_back(creature); +} + +void Tile::removeWalkingCreature(const CreaturePtr& creature) +{ + auto it = std::find(m_walkingCreatures.begin(), m_walkingCreatures.end(), creature); + if(it != m_walkingCreatures.end()) + m_walkingCreatures.erase(it); +} + ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos) { if(!thing) diff --git a/src/otclient/core/tile.h b/src/otclient/core/tile.h index 7cd3a4d3..e55badbc 100644 --- a/src/otclient/core/tile.h +++ b/src/otclient/core/tile.h @@ -33,12 +33,12 @@ public: void draw(const Point& dest, float scaleFactor, int drawFlags); -private: - void updateVisibleItemsCache(); - public: void clean(); + void addWalkingCreature(const CreaturePtr& creature); + void removeWalkingCreature(const CreaturePtr& creature); + ThingPtr addThing(const ThingPtr& thing, int stackPos = -1); bool removeThing(const ThingPtr& thing); ThingPtr getThing(int stackPos); @@ -70,6 +70,7 @@ public: TilePtr asTile() { return std::static_pointer_cast(shared_from_this()); } private: + std::vector m_walkingCreatures; std::vector m_effects; // leave this outside m_things because it has no stackpos. std::vector m_things; Position m_position;