mirror of
https://github.com/mehah/otclient
synced 2026-08-15 16:29:06 -04:00
Merge branch 'main' into feat/otui-editor
This commit is contained in:
commit
f71d252be3
7 changed files with 100 additions and 38 deletions
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "animator.h"
|
||||
#include "attachedeffect.h"
|
||||
#include "client/const.h"
|
||||
#include "game.h"
|
||||
#include "gameconfig.h"
|
||||
#include "lightview.h"
|
||||
|
|
@ -741,12 +742,22 @@ void Creature::updateWalkingTile()
|
|||
g_gameConfig.getSpriteSize() + (m_walkOffset.y - displacementY),
|
||||
g_gameConfig.getSpriteSize(), g_gameConfig.getSpriteSize());
|
||||
|
||||
if (m_walkedPixels < g_gameConfig.getSpriteSize() / 2) {
|
||||
if (m_direction == Otc::Direction::NorthWest)
|
||||
newWalkingTile = m_walkingTile ? m_walkingTile : getTile();
|
||||
else if (m_direction == Otc::Direction::SouthEast)
|
||||
newWalkingTile = g_map.getTile(getPosition().translated(-1, -1, 0));
|
||||
}
|
||||
|
||||
for (int xi = -1; xi <= 1 && !newWalkingTile; ++xi) {
|
||||
for (int yi = -1; yi <= 1 && !newWalkingTile; ++yi) {
|
||||
Rect virtualTileRect((xi + 1) * g_gameConfig.getSpriteSize(), (yi + 1) * g_gameConfig.getSpriteSize(), g_gameConfig.getSpriteSize(), g_gameConfig.getSpriteSize());
|
||||
|
||||
// only render creatures where bottom right is inside tile rect
|
||||
if (virtualTileRect.contains(virtualCreatureRect.bottomRight())) {
|
||||
// when creature is moving to the upper left tile, because of drawing order (we want creature to be behind the object to the left if its a tree for example)
|
||||
if (m_direction == Otc::Direction::NorthWest && virtualTileRect.contains(virtualCreatureRect.topLeft())) {
|
||||
newWalkingTile = g_map.getOrCreateTile(getPosition().translated(xi, yi, 0));
|
||||
} else if (virtualTileRect.contains(virtualCreatureRect.bottomRight())) {
|
||||
// only render creatures where bottom right is inside tile rect
|
||||
newWalkingTile = g_map.getOrCreateTile(getPosition().translated(xi, yi, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "map.h"
|
||||
|
||||
#include "animatedtext.h"
|
||||
#include "client/const.h"
|
||||
#include "creatures.h"
|
||||
#include "game.h"
|
||||
#include "gameconfig.h"
|
||||
|
|
@ -1249,7 +1250,7 @@ bool Map::removeAttachedWidgetFromObject(const UIWidgetPtr& widget) {
|
|||
|
||||
void Map::updateAttachedWidgets(const MapViewPtr& mapView)
|
||||
{
|
||||
g_drawPool.select(DrawPoolType::MAP);
|
||||
bool should_repaint = false;
|
||||
for (const auto& [widget, object] : m_attachedObjectWidgetMap) {
|
||||
if (widget->isDestroyed()) {
|
||||
continue;
|
||||
|
|
@ -1300,9 +1301,16 @@ void Map::updateAttachedWidgets(const MapViewPtr& mapView)
|
|||
const auto& widgetRect = widget->getRect();
|
||||
const auto& newWidgetRect = Rect(p, widgetRect.width(), widgetRect.height());
|
||||
|
||||
widget->disableUpdateTemporarily();
|
||||
widget->setRect(newWidgetRect);
|
||||
if (widgetRect != newWidgetRect) {
|
||||
widget->disableUpdateTemporarily();
|
||||
widget->setRect(newWidgetRect);
|
||||
should_repaint = true;
|
||||
}
|
||||
}
|
||||
|
||||
// only repaint if some widget changed position on the screen
|
||||
if (should_repaint)
|
||||
g_drawPool.repaint(DrawPoolType::FOREGROUND);
|
||||
}
|
||||
|
||||
std::map<std::string, std::tuple<int, int, int, std::string>> Map::findEveryPath(const Position& start, int maxDistance, const std::map<std::string, std::string>& params)
|
||||
|
|
@ -1543,4 +1551,4 @@ const TilePtr& TileBlock::getOrCreate(const Position& pos)
|
|||
if (!tile)
|
||||
tile = std::make_shared<Tile>(pos);
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ void MapView::drawFloor()
|
|||
const bool alwaysTransparent = m_floorViewMode == Otc::ALWAYS_WITH_TRANSPARENCY && z < m_cachedFirstVisibleFloor && _camera.coveredUp(cameraPosition.z - z);
|
||||
|
||||
const auto& map = m_floors[z].cachedVisibleTiles;
|
||||
std::vector<TilePtr> walking_tiles;
|
||||
|
||||
for (const auto& tile : map.tiles) {
|
||||
uint32_t tileFlags = flags;
|
||||
|
|
@ -148,15 +149,27 @@ void MapView::drawFloor()
|
|||
if (!m_drawViewportEdge && !tile->canRender(tileFlags, cameraPosition, m_viewport))
|
||||
continue;
|
||||
|
||||
if (alwaysTransparent) {
|
||||
const bool inRange = tile->getPosition().isInRange(_camera, g_gameConfig.getTileTransparentFloorViewRange(), g_gameConfig.getTileTransparentFloorViewRange(), true);
|
||||
g_drawPool.setOpacity(inRange ? .16 : .7);
|
||||
walking_tiles.emplace_back(tile);
|
||||
|
||||
// if this tile is the edge or if upper right tile doesn't have walking creatures
|
||||
// -> draw it and all walking_tiles depending on it (if there are any queued up)
|
||||
TilePtr upper_right_tile = g_map.getTile(tile->getPosition().translated(1, -1, 0));
|
||||
if (!upper_right_tile || !upper_right_tile->hasWalkingCreature()) {
|
||||
for (int i = walking_tiles.size() - 1; i >= 0; i--) {
|
||||
auto const &tile = walking_tiles[i];
|
||||
|
||||
if (alwaysTransparent) {
|
||||
const bool inRange = tile->getPosition().isInRange(_camera, g_gameConfig.getTileTransparentFloorViewRange(), g_gameConfig.getTileTransparentFloorViewRange(), true);
|
||||
g_drawPool.setOpacity(inRange ? .16 : .7);
|
||||
}
|
||||
|
||||
tile->draw(m_posInfo, transformPositionTo2D(tile->getPosition()), tileFlags);
|
||||
|
||||
if (alwaysTransparent)
|
||||
g_drawPool.resetOpacity();
|
||||
}
|
||||
walking_tiles.clear();
|
||||
}
|
||||
|
||||
tile->draw(m_posInfo, transformPositionTo2D(tile->getPosition()), tileFlags);
|
||||
|
||||
if (alwaysTransparent)
|
||||
g_drawPool.resetOpacity();
|
||||
}
|
||||
|
||||
for (const auto& missile : g_map.getFloorMissiles(z))
|
||||
|
|
|
|||
|
|
@ -78,6 +78,28 @@ void Tile::draw(const MapPosInfo& mapRect, const Point& dest, const int flags, L
|
|||
return;
|
||||
}
|
||||
|
||||
// when walking diagonally over a tile that has a object on it like a tree the creature should be rendered behind it
|
||||
// i.e. render creature first then the tree
|
||||
if (hasWalkingCreature()) {
|
||||
g_drawPool.setDrawOrder(DrawOrder::THIRD);
|
||||
for (const auto& creature : m_walkingCreatures) {
|
||||
if (creature->getDirection() == Otc::Direction::NorthEast || creature->getDirection() == Otc::Direction::SouthWest) {
|
||||
const auto& cDest = Point(
|
||||
dest.x + ((creature->getPosition().x - m_position.x) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor(),
|
||||
dest.y + ((creature->getPosition().y - m_position.y) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor()
|
||||
);
|
||||
|
||||
if (flags == Otc::DrawLights)
|
||||
creature->drawLight(cDest, lightView);
|
||||
else {
|
||||
creature->draw(cDest, flags & Otc::DrawThings);
|
||||
creature->drawInformation(mapRect, cDest, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_drawPool.resetDrawOrder();
|
||||
}
|
||||
|
||||
for (const auto& thing : m_things) {
|
||||
if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
|
||||
break;
|
||||
|
|
@ -133,6 +155,26 @@ void Tile::drawCreature(const MapPosInfo& mapRect, const Point& dest, const int
|
|||
if (!forceDraw && !m_drawTopAndCreature)
|
||||
return;
|
||||
|
||||
g_drawPool.setDrawOrder(DrawOrder::THIRD);
|
||||
for (const auto& creature : m_walkingCreatures) {
|
||||
// already drawn by this point
|
||||
if (creature->getDirection() == Otc::Direction::NorthEast || creature->getDirection() == Otc::Direction::SouthWest)
|
||||
continue;
|
||||
|
||||
const auto& cDest = Point(
|
||||
dest.x + ((creature->getPosition().x - m_position.x) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor(),
|
||||
dest.y + ((creature->getPosition().y - m_position.y) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor()
|
||||
);
|
||||
|
||||
if (flags == Otc::DrawLights)
|
||||
creature->drawLight(cDest, lightView);
|
||||
else {
|
||||
creature->draw(cDest, flags & Otc::DrawThings);
|
||||
creature->drawInformation(mapRect, cDest, flags);
|
||||
}
|
||||
}
|
||||
g_drawPool.resetDrawOrder();
|
||||
|
||||
bool localPlayerDrawed = false;
|
||||
if (hasCreatures()) {
|
||||
for (const auto& thing : m_things) {
|
||||
|
|
@ -148,22 +190,6 @@ void Tile::drawCreature(const MapPosInfo& mapRect, const Point& dest, const int
|
|||
}
|
||||
}
|
||||
|
||||
g_drawPool.setDrawOrder(DrawOrder::THIRD);
|
||||
for (const auto& creature : m_walkingCreatures) {
|
||||
const auto& cDest = Point(
|
||||
dest.x + ((creature->getPosition().x - m_position.x) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor(),
|
||||
dest.y + ((creature->getPosition().y - m_position.y) * g_gameConfig.getSpriteSize() - creature->getDrawElevation()) * g_drawPool.getScaleFactor()
|
||||
);
|
||||
|
||||
if (flags == Otc::DrawLights)
|
||||
creature->drawLight(cDest, lightView);
|
||||
else {
|
||||
creature->draw(cDest, flags & Otc::DrawThings);
|
||||
creature->drawInformation(mapRect, cDest, flags);
|
||||
}
|
||||
}
|
||||
g_drawPool.resetDrawOrder();
|
||||
|
||||
// draw the local character if he is on a virtual tile, that is, his visual position is not the same as the server.
|
||||
if (!localPlayerDrawed && g_game.getLocalPlayer() && !g_game.getLocalPlayer()->isWalking() && g_game.getLocalPlayer()->getPosition() == m_position) {
|
||||
drawThing(g_game.getLocalPlayer(), dest, flags, drawElevation, lightView);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public:
|
|||
|
||||
bool hasCreatures() const { return (m_thingTypeFlag & HAS_CREATURE) != 0; }
|
||||
bool hasCreatures() { return static_cast<const Tile&>(*this).hasCreatures(); }
|
||||
bool hasWalkingCreature() { return !m_walkingCreatures.empty(); }
|
||||
|
||||
void appendSpectators(std::vector<CreaturePtr>& out) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,8 @@ bool GraphicalApplication::canDrawMap() const {
|
|||
if (!m_drawEvents->canDraw(MAP))
|
||||
return false;
|
||||
|
||||
static constexpr std::array<DrawPoolType, 4> types{ MAP, LIGHT, FOREGROUND_MAP, CREATURE_INFORMATION };
|
||||
// FOREGROUND is here only because of attached widgets on the map (like tile widgets)
|
||||
static constexpr std::array<DrawPoolType, 5> types{ MAP, LIGHT, FOREGROUND_MAP, CREATURE_INFORMATION, FOREGROUND };
|
||||
|
||||
for (DrawPoolType type : types) {
|
||||
if (g_drawPool.isDrawing(type))
|
||||
|
|
@ -212,7 +213,7 @@ void GraphicalApplication::run()
|
|||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
if (g_game.isOnline()) {
|
||||
AutoStat s(STATS_RENDER, "DrawPreload");
|
||||
m_drawEvents->preLoad();
|
||||
}
|
||||
|
|
@ -222,11 +223,13 @@ void GraphicalApplication::run()
|
|||
if (!g_game.isOnline() && canDrawForeground) {
|
||||
AutoStat s(STATS_RENDER, "DrawForegroundUI");
|
||||
g_ui.render(DrawPoolType::FOREGROUND);
|
||||
} else if (canDrawMap() && canDrawForeground) {
|
||||
tasks.emplace_back(g_asyncDispatcher->submit_task([] {
|
||||
AutoStat s(STATS_RENDER, "DrawForegroundUI");
|
||||
g_ui.render(DrawPoolType::FOREGROUND);
|
||||
}));
|
||||
} else if (canDrawMap()) {
|
||||
if (canDrawForeground) {
|
||||
tasks.emplace_back(g_asyncDispatcher->submit_task([] {
|
||||
AutoStat s(STATS_RENDER, "DrawForegroundUI");
|
||||
g_ui.render(DrawPoolType::FOREGROUND);
|
||||
}));
|
||||
}
|
||||
|
||||
static constexpr std::array<DrawPoolType, 2> types{ DrawPoolType::LIGHT, DrawPoolType::FOREGROUND_MAP };
|
||||
for (const auto type : types) {
|
||||
|
|
|
|||
|
|
@ -524,4 +524,4 @@ std::shared_ptr<CoordsBuffer> DrawPool::getCoordsBuffer() {
|
|||
delete ptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue