Skip to content

Commit 6a767c3

Browse files
committed
Core/MMaps: Implemented dynamic mmap tile rebuilding for destructible objects
1 parent 556505d commit 6a767c3

File tree

10 files changed

+564
-14
lines changed

10 files changed

+564
-14
lines changed

src/common/Collision/DynamicTree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ int CHECK_TREE_PERIOD = 200;
3636
} // namespace
3737

3838
template<> struct PositionTrait< GameObjectModel> {
39-
static void getPosition(GameObjectModel const& g, G3D::Vector3& p) { p = g.getPosition(); }
39+
static void getPosition(GameObjectModel const& g, G3D::Vector3& p) { p = g.GetPosition(); }
4040
};
4141

4242
template<> struct BoundsTrait< GameObjectModel> {

src/common/Collision/Models/GameObjectModel.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,11 @@
2121
#include "Define.h"
2222
#include <G3D/AABox.h>
2323
#include <G3D/Matrix3.h>
24+
#include <G3D/Quat.h>
2425
#include <G3D/Ray.h>
2526
#include <G3D/Vector3.h>
2627
#include <memory>
2728

28-
namespace G3D
29-
{
30-
class Quat;
31-
}
32-
3329
namespace VMAP
3430
{
3531
class WorldModel;
@@ -53,25 +49,33 @@ class TC_COMMON_API GameObjectModelOwnerBase
5349
virtual bool IsInPhase(PhaseShift const& /*phaseShift*/) const = 0;
5450
virtual G3D::Vector3 GetPosition() const = 0;
5551
virtual G3D::Quat GetRotation() const = 0;
52+
virtual int64 GetPackedRotation() const = 0;
5653
virtual float GetScale() const = 0;
5754
virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const = 0;
5855
};
5956

6057
class TC_COMMON_API GameObjectModel /*, public Intersectable*/
6158
{
62-
GameObjectModel() : iCollisionEnabled(false), iLosBlockingDisabled(false), iInvScale(0), iScale(0), iModel(nullptr) { }
59+
GameObjectModel() : iCollisionEnabled(false), iLosBlockingDisabled(false), iIncludeInNavMesh(false), iInvScale(0), iScale(0), iModel(nullptr) { }
6360
public:
6461
const G3D::AABox& getBounds() const { return iBound; }
6562

6663
~GameObjectModel();
6764

68-
const G3D::Vector3& getPosition() const { return iPos;}
65+
uint32 GetDisplayId() const { return owner->GetDisplayId(); }
66+
G3D::Vector3 const& GetPosition() const { return iPos; }
67+
G3D::Quat GetRotation() const { return owner->GetRotation(); }
68+
G3D::Matrix3 const& GetInvRot() const { return iInvRot; }
69+
int64 GetPackedRotation() const { return owner->GetPackedRotation(); }
70+
float GetScale() const { return iScale; }
6971

7072
/* Enables/disables collision */
7173
void EnableCollision(bool enable) { iCollisionEnabled = enable; }
7274
bool IsCollisionEnabled() const { return iCollisionEnabled; }
7375
void DisableLosBlocking(bool enable) { iLosBlockingDisabled = enable; }
7476
bool IsLosBlockingDisabled() const { return iLosBlockingDisabled; }
77+
void IncludeInNavMesh(bool enable) { iIncludeInNavMesh = enable; }
78+
bool IsIncludedInNavMesh() const { return iIncludeInNavMesh; }
7579
bool IsMapObject() const;
7680
uint8 GetNameSetId() const { return owner->GetNameSetId(); }
7781

@@ -83,11 +87,14 @@ class TC_COMMON_API GameObjectModel /*, public Intersectable*/
8387

8488
bool UpdatePosition();
8589

90+
std::shared_ptr<VMAP::WorldModel const> GetWorldModel() const { return iModel; }
91+
8692
private:
8793
bool initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
8894

8995
bool iCollisionEnabled; ///< Is model ignored in all checks
9096
bool iLosBlockingDisabled; ///< Is model ignored during line of sight checks (but is always included in location/height checks)
97+
bool iIncludeInNavMesh; ///< Is model included when generating navigation mesh
9198
G3D::AABox iBound;
9299
G3D::Matrix3 iInvRot;
93100
G3D::Vector3 iPos;

src/common/Collision/RegularGrid.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,13 @@ class TC_COMMON_API RegularGrid2D
210210
if (Node* node = nodes[cell.x][cell.y].get())
211211
node->intersectRay(ray, intersectCallback, max_dist);
212212
}
213+
214+
std::span<T const* const> getObjects(int x, int y) const
215+
{
216+
if (Node* n = nodes[x][y].get())
217+
return n->getObjects();
218+
return {};
219+
}
213220
};
214221

215222
#undef CELL_SIZE

src/common/mmaps_common/Management/MMapManager.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,21 @@ namespace MMAP
5050
// we have to use single dtNavMeshQuery for every instance, since those are not thread safe
5151
NavMeshQuerySet navMeshQueries; // instanceId to query
5252

53-
static uint32 GetInstanceIdForMeshLookup([[maybe_unused]] uint32 mapId, [[maybe_unused]] uint32 instanceId)
53+
static uint32 GetInstanceIdForMeshLookup(uint32 mapId, uint32 instanceId)
5454
{
55+
switch (mapId)
56+
{
57+
case 0: case 1: case 571: case 603: case 607: case 609: case 616: case 628: case 631: case 644: case 649: case 720:
58+
case 732: case 754: case 755: case 861: case 938: case 940: case 962: case 967: case 1064: case 1076: case 1098:
59+
case 1122: case 1126: case 1182: case 1205: case 1220: case 1265: case 1492: case 1523: case 1530: case 1579: case 1676:
60+
case 1704: case 1705: case 1706: case 1707: case 1734: case 1756: case 1943: case 2076: case 2118: case 2160: case 2161:
61+
case 2187: case 2212: case 2235: case 2237: case 2264: case 2450: case 2512: case 2586: case 2601: case 2654: case 2657:
62+
case 2660: case 2669: case 2819: case 2828:
63+
return instanceId;
64+
default:
65+
break;
66+
}
67+
5568
// for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances
5669
return 0;
5770
}
@@ -103,6 +116,11 @@ namespace MMAP
103116
return itr;
104117
}
105118

119+
bool MMapManager::isRebuildingTilesEnabledOnMap(uint32 mapId)
120+
{
121+
return MMapData::GetInstanceIdForMeshLookup(mapId, 1) != 0;
122+
}
123+
106124
LoadResult MMapManager::loadMapData(std::string_view basePath, uint32 mapId, uint32 instanceId)
107125
{
108126
// we already have this map loaded?
@@ -441,7 +459,7 @@ namespace MMAP
441459
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId {:04} instanceId {}", instanceMapId, instanceId);
442460
}
443461

444-
dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId, uint32 instanceId)
462+
dtNavMesh* MMapManager::GetNavMesh(uint32 mapId, uint32 instanceId)
445463
{
446464
MMapDataSet::const_iterator itr = GetMMapData(mapId);
447465
if (itr == loadedMMaps.end())

src/common/mmaps_common/Management/MMapManager.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ namespace MMAP
6767

6868
// the returned [dtNavMeshQuery const*] is NOT threadsafe
6969
dtNavMeshQuery const* GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId);
70-
dtNavMesh const* GetNavMesh(uint32 mapId, uint32 instanceId);
70+
dtNavMesh* GetNavMesh(uint32 mapId, uint32 instanceId);
7171

7272
uint32 getLoadedTilesCount() const { return loadedTiles; }
7373
uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); }
74+
75+
static bool isRebuildingTilesEnabledOnMap(uint32 mapId);
76+
7477
private:
7578
LoadResult loadMapData(std::string_view basePath, uint32 mapId, uint32 instanceId);
7679
uint32 packTileID(int32 x, int32 y);

src/server/game/Entities/GameObject/GameObject.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,7 +4014,7 @@ void GameObject::UpdateModel()
40144014
modelCollisionEnabled = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : (GetGoState() == GO_STATE_READY || IsTransport());
40154015

40164016
RemoveFlag(GO_FLAG_MAP_OBJECT);
4017-
m_model = nullptr;
4017+
std::unique_ptr<GameObjectModel> oldModel = std::exchange(m_model, nullptr);
40184018

40194019
CreateModel();
40204020
if (m_model)
@@ -4023,6 +4023,23 @@ void GameObject::UpdateModel()
40234023
if (modelCollisionEnabled)
40244024
m_model->EnableCollision(modelCollisionEnabled);
40254025
}
4026+
4027+
switch (GetGoType())
4028+
{
4029+
// Only update navmesh when display id changes and not on spawn
4030+
// default state of destructible buildings is intended to be baked in the mesh produced by mmaps_generator
4031+
case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
4032+
case GAMEOBJECT_TYPE_TRAPDOOR:
4033+
case GAMEOBJECT_TYPE_PHASEABLE_MO:
4034+
case GAMEOBJECT_TYPE_SIEGEABLE_MO:
4035+
if (m_model)
4036+
GetMap()->RequestRebuildNavMeshOnGameObjectModelChange(*m_model, GetPhaseShift());
4037+
else if (oldModel)
4038+
GetMap()->RequestRebuildNavMeshOnGameObjectModelChange(*oldModel, GetPhaseShift());
4039+
break;
4040+
default:
4041+
break;
4042+
}
40264043
}
40274044

40284045
bool GameObject::IsLootAllowedFor(Player const* player) const
@@ -4499,6 +4516,7 @@ class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase
44994516
bool IsInPhase(PhaseShift const& phaseShift) const override { return _owner->GetPhaseShift().CanSee(phaseShift); }
45004517
G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
45014518
G3D::Quat GetRotation() const override { return G3D::Quat(_owner->GetLocalRotation().x, _owner->GetLocalRotation().y, _owner->GetLocalRotation().z, _owner->GetLocalRotation().w); }
4519+
int64 GetPackedRotation() const override { return _owner->GetPackedLocalRotation(); }
45024520
float GetScale() const override { return _owner->GetObjectScale(); }
45034521
void DebugVisualizeCorner(G3D::Vector3 const& corner) const override { _owner->SummonCreature(1, corner.x, corner.y, corner.z, 0, TEMPSUMMON_MANUAL_DESPAWN); }
45044522

@@ -4538,8 +4556,20 @@ void GameObject::CreateModel()
45384556
if (m_model->IsMapObject())
45394557
SetFlag(GO_FLAG_MAP_OBJECT);
45404558

4541-
if (GetGoType() == GAMEOBJECT_TYPE_DOOR)
4542-
m_model->DisableLosBlocking(GetGOInfo()->door.NotLOSBlocking);
4559+
switch (GetGoType())
4560+
{
4561+
case GAMEOBJECT_TYPE_DOOR:
4562+
m_model->DisableLosBlocking(GetGOInfo()->door.NotLOSBlocking);
4563+
break;
4564+
case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
4565+
case GAMEOBJECT_TYPE_TRAPDOOR:
4566+
case GAMEOBJECT_TYPE_PHASEABLE_MO:
4567+
case GAMEOBJECT_TYPE_SIEGEABLE_MO:
4568+
m_model->IncludeInNavMesh(true);
4569+
break;
4570+
default:
4571+
break;
4572+
}
45434573
}
45444574
}
45454575

0 commit comments

Comments
 (0)