diff --git a/src/otclient/const.h b/src/otclient/const.h index e3879329..f80b9eb0 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -59,17 +59,19 @@ namespace Otc enum DrawFlags { DrawGround = 1, - DrawWalls = 2, - DrawCommonItems = 4, - DrawCreatures = 8, - DrawEffects = 16, - DrawMissiles = 32, - DrawCreaturesInformation = 64, - DrawStaticTexts = 128, - DrawAnimatedTexts = 256, - DrawAnimations = 512, - DrawGroundBorders = 1024, - DrawEverything = DrawGround | DrawGroundBorders | DrawWalls | DrawCommonItems | + DrawGroundBorders = 2, + DrawOnBottom = 4, + DrawOnTop = 8, + DrawItems = 16, + DrawCreatures = 32, + DrawEffects = 64, + DrawMissiles = 128, + DrawCreaturesInformation = 256, + DrawStaticTexts = 512, + DrawAnimatedTexts = 1024, + DrawAnimations = 2048, + DrawWalls = DrawOnBottom | DrawOnTop, + DrawEverything = DrawGround | DrawGroundBorders | DrawWalls | DrawItems | DrawCreatures | DrawEffects | DrawMissiles | DrawCreaturesInformation | DrawStaticTexts | DrawAnimatedTexts | DrawAnimations }; diff --git a/src/otclient/core/map.h b/src/otclient/core/map.h index 6e153c80..a403fc0d 100644 --- a/src/otclient/core/map.h +++ b/src/otclient/core/map.h @@ -70,7 +70,7 @@ public: Position getCentralPosition() { return m_centralPosition; } int getFirstAwareFloor(); int getLastAwareFloor(); - + const std::vector& getFloorMissiles(int z) { return m_floorMissiles[z]; } std::vector getAnimatedTexts() { return m_animatedTexts; } std::vector getStaticTexts() { return m_staticTexts; } diff --git a/src/otclient/core/mapview.cpp b/src/otclient/core/mapview.cpp index ec17740d..1a8e2f75 100644 --- a/src/otclient/core/mapview.cpp +++ b/src/otclient/core/mapview.cpp @@ -31,6 +31,7 @@ #include "tile.h" #include "statictext.h" #include "animatedtext.h" +#include "missile.h" #include MapView::MapView() @@ -58,30 +59,40 @@ void MapView::draw(const Rect& rect) float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS; Position cameraPosition = getCameraPosition(); - int tileDrawFlags = 0; + int drawFlags = 0; if(m_viewRange == NEAR_VIEW) - tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawAnimations; + drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | + Otc::DrawItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawMissiles | Otc::DrawAnimations; else if(m_viewRange == MID_VIEW) - tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawCommonItems; + drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems; else if(m_viewRange == FAR_VIEW) - tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls; + drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls; else if(m_tileSize >= 4) // HUGE_VIEW 1 - tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders; + drawFlags = Otc::DrawGround | Otc::DrawGroundBorders; else // HUGE_VIEW 2 - tileDrawFlags = Otc::DrawGround; + drawFlags = Otc::DrawGround; - bool animate = m_animated; - - // only animate in near views - if(m_viewRange != NEAR_VIEW) - animate = false; - - if(m_mustDrawVisibleTilesCache || animate) { + if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) { m_framebuffer->bind(m_mustCleanFramebuffer); - for(const TilePtr& tile : m_cachedVisibleTiles) { - tile->draw(transformPositionTo2D(tile->getPosition()), scaleFactor, tileDrawFlags); - //TODO: restore missiles + auto it = m_cachedVisibleTiles.begin(); + auto end = m_cachedVisibleTiles.end(); + for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) { + while(it != end) { + const TilePtr& tile = *it; + if(tile->getPosition().z != z) + break; + else + ++it; + + tile->draw(transformPositionTo2D(tile->getPosition()), scaleFactor, drawFlags); + } + + if(drawFlags & Otc::DrawMissiles) { + for(const MissilePtr& missile : g_map.getFloorMissiles(z)) { + missile->draw(transformPositionTo2D(missile->getPosition()), scaleFactor, drawFlags & Otc::DrawAnimations); + } + } } m_framebuffer->generateMipmaps(); m_framebuffer->release(); diff --git a/src/otclient/core/missile.cpp b/src/otclient/core/missile.cpp index 494f578a..8b09ac08 100644 --- a/src/otclient/core/missile.cpp +++ b/src/otclient/core/missile.cpp @@ -27,54 +27,43 @@ #include #include -void Missile::draw(const Point& p, const Rect&) +void Missile::draw(const Point& dest, float scaleFactor, bool animate) { - if(m_id == 0) + if(m_id == 0 || !animate) return; - /* - float time = (g_clock.ticks() - m_startTicks) / m_duration; - int xPattern = 0, yPattern = 0; - if(direction == Otc::NorthWest) { + if(m_direction == Otc::NorthWest) { xPattern = 0; yPattern = 0; - } - else if(direction == Otc::North) { - m_xPattern = 1; - m_yPattern = 0; - } - else if(direction == Otc::NorthEast) { - m_xPattern = 2; - m_yPattern = 0; - } - else if(direction == Otc::East) { - m_xPattern = 2; - m_yPattern = 1; - } - else if(direction == Otc::SouthEast) { - m_xPattern = 2; - m_yPattern = 2; - } - else if(direction == Otc::South) { - m_xPattern = 1; - m_yPattern = 2; - } - else if(direction == Otc::SouthWest) { - m_xPattern = 0; - m_yPattern = 2; - } - else if(direction == Otc::West) { - m_xPattern = 0; - m_yPattern = 1; - } - else { - m_xPattern = 1; - m_yPattern = 1; + } else if(m_direction == Otc::North) { + xPattern = 1; + yPattern = 0; + } else if(m_direction == Otc::NorthEast) { + xPattern = 2; + yPattern = 0; + } else if(m_direction == Otc::East) { + xPattern = 2; + yPattern = 1; + } else if(m_direction == Otc::SouthEast) { + xPattern = 2; + yPattern = 2; + } else if(m_direction == Otc::South) { + xPattern = 1; + yPattern = 2; + } else if(m_direction == Otc::SouthWest) { + xPattern = 0; + yPattern = 2; + } else if(m_direction == Otc::West) { + xPattern = 0; + yPattern = 1; + } else { + xPattern = 1; + yPattern = 1; } - //internalDraw(p + Point(m_deltax * time, m_deltay * time), 0, 0); - */ + float fraction = m_animationTimer.ticksElapsed() / m_duration; + internalDraw(dest + m_delta * fraction * scaleFactor, scaleFactor, xPattern, yPattern, 0, 0); } void Missile::setPath(const Position& fromPosition, const Position& toPosition) @@ -82,11 +71,9 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition) m_direction = fromPosition.getDirectionFromPosition(toPosition); m_position = fromPosition; - m_deltax = toPosition.x - fromPosition.x; - m_deltay = toPosition.y - fromPosition.y; - m_duration = 150 * std::sqrt(Point(m_deltax, m_deltay).length()); - m_deltax *= Otc::TILE_PIXELS; - m_deltay *= Otc::TILE_PIXELS; + m_delta = Point(toPosition.x - fromPosition.x, toPosition.y - fromPosition.y); + m_duration = 150 * std::sqrt(m_delta.length()); + m_delta *= Otc::TILE_PIXELS; m_animationTimer.restart(); // schedule removal diff --git a/src/otclient/core/missile.h b/src/otclient/core/missile.h index a89ca50f..4b3a48fc 100644 --- a/src/otclient/core/missile.h +++ b/src/otclient/core/missile.h @@ -34,7 +34,7 @@ class Missile : public Thing }; public: - void draw(const Point& p, const Rect&); + void draw(const Point& dest, float scaleFactor, bool animate); void updateAnimation(); @@ -47,8 +47,7 @@ public: private: Timer m_animationTimer; - int m_deltax; - int m_deltay; + Point m_delta; float m_duration; uint16 m_id; Otc::Direction m_direction; diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index 63f8d27f..9ed7dfef 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -42,14 +42,14 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) bool animate = drawFlags & Otc::DrawAnimations; // first bottom items - if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawGroundBorders || drawFlags & Otc::DrawCommonItems) { + if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) { for(const ThingPtr& thing : m_things) { if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom()) break; if((thing->isGround() && drawFlags & Otc::DrawGround) || (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) || - (thing->isOnBottom() && drawFlags & Otc::DrawCommonItems)) + (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate); drawElevation += thing->getElevation(); @@ -58,10 +58,10 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) } } - int redrawPreviousOnTopW = 0; - int redrawPreviousOnTopH = 0; + int redrawPreviousTopW = 0; + int redrawPreviousTopH = 0; - if(drawFlags & Otc::DrawCommonItems) { + if(drawFlags & Otc::DrawItems) { // now common items in reverse order for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { const ThingPtr& thing = *it; @@ -70,8 +70,8 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate); if(thing->isLyingCorpse()) { - redrawPreviousOnTopW = std::max(thing->getDimensionWidth(), redrawPreviousOnTopW); - redrawPreviousOnTopH = std::max(thing->getDimensionHeight(), redrawPreviousOnTopH); + redrawPreviousTopW = std::max(thing->getDimensionWidth(), redrawPreviousTopW); + redrawPreviousTopH = std::max(thing->getDimensionHeight(), redrawPreviousTopH); } drawElevation += thing->getElevation(); @@ -80,18 +80,17 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) } } - // must redraw previous creatures/ontop above lying corpses - if(redrawPreviousOnTopH > 0 || redrawPreviousOnTopW > 0) { - int onTopRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawWalls); - if(onTopRedrawFlags) { - for(int y=-redrawPreviousOnTopH;y<=0;++y) { - for(int x=-redrawPreviousOnTopW;x<=0;++x) { + // after we render 2x2 lying corpses, we must redraw previous creatures/ontop above them + if(redrawPreviousTopH > 0 || redrawPreviousTopW > 0) { + int topRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawOnTop | Otc::DrawAnimations); + if(topRedrawFlags) { + for(int y=-redrawPreviousTopH;y<=0;++y) { + for(int x=-redrawPreviousTopW;x<=0;++x) { if(x == 0 && y == 0) continue; const TilePtr& tile = g_map.getTile(m_position.translated(x,y)); - if(tile) { - tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, onTopRedrawFlags); - } + if(tile) + tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags); } } } @@ -121,7 +120,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) } // top items - if(drawFlags & Otc::DrawWalls) { + if(drawFlags & Otc::DrawOnTop) { for(const ThingPtr& thing : m_things) { if(thing->isOnTop()) thing->draw(dest - drawElevation, scaleFactor, animate);