diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp
index d20f31b0b..b66f8d4cd 100644
--- a/Source/Engine/Networking/NetworkReplicator.cpp
+++ b/Source/Engine/Networking/NetworkReplicator.cpp
@@ -861,7 +861,7 @@ void NetworkReplicator::DespawnObject(ScriptingObject* obj)
DeleteNetworkObject(obj);
}
-uint32 NetworkReplicator::GetObjectOwnerClientId(ScriptingObject* obj)
+uint32 NetworkReplicator::GetObjectOwnerClientId(const ScriptingObject* obj)
{
uint32 id = NetworkManager::ServerClientId;
if (obj)
@@ -870,11 +870,23 @@ uint32 NetworkReplicator::GetObjectOwnerClientId(ScriptingObject* obj)
const auto it = Objects.Find(obj->GetID());
if (it != Objects.End())
id = it->Item.OwnerClientId;
+ else
+ {
+ for (const SpawnItem& item : SpawnQueue)
+ {
+ if (item.Object == obj)
+ {
+ if (item.HasOwnership)
+ id = item.OwnerClientId;
+ break;
+ }
+ }
+ }
}
return id;
}
-NetworkObjectRole NetworkReplicator::GetObjectRole(ScriptingObject* obj)
+NetworkObjectRole NetworkReplicator::GetObjectRole(const ScriptingObject* obj)
{
NetworkObjectRole role = NetworkObjectRole::None;
if (obj)
@@ -883,6 +895,18 @@ NetworkObjectRole NetworkReplicator::GetObjectRole(ScriptingObject* obj)
const auto it = Objects.Find(obj->GetID());
if (it != Objects.End())
role = it->Item.Role;
+ else
+ {
+ for (const SpawnItem& item : SpawnQueue)
+ {
+ if (item.Object == obj)
+ {
+ if (item.HasOwnership)
+ role = item.Role;
+ break;
+ }
+ }
+ }
}
return role;
}
@@ -901,6 +925,18 @@ void NetworkReplicator::SetObjectOwnership(ScriptingObject* obj, uint32 ownerCli
auto& item = SpawnQueue[i];
if (item.Object == obj)
{
+#if !BUILD_RELEASE
+ if (ownerClientId == NetworkManager::LocalClientId)
+ {
+ // Ensure local client owns that object actually
+ CHECK(localRole == NetworkObjectRole::OwnedAuthoritative);
+ }
+ else
+ {
+ // Ensure local client doesn't own that object since it's owned by other client
+ CHECK(localRole != NetworkObjectRole::OwnedAuthoritative);
+ }
+#endif
item.HasOwnership = true;
item.HierarchicalOwnership = hierarchical;
item.OwnerClientId = ownerClientId;
diff --git a/Source/Engine/Networking/NetworkReplicator.h b/Source/Engine/Networking/NetworkReplicator.h
index e0893cc64..389350e5f 100644
--- a/Source/Engine/Networking/NetworkReplicator.h
+++ b/Source/Engine/Networking/NetworkReplicator.h
@@ -104,14 +104,14 @@ public:
///
/// The network object.
/// The Client Id.
- API_FUNCTION() static uint32 GetObjectOwnerClientId(ScriptingObject* obj);
+ API_FUNCTION() static uint32 GetObjectOwnerClientId(const ScriptingObject* obj);
///
/// Gets the role of the network object used locally (eg. to check if can simulate object).
///
/// The network object.
/// The object role.
- API_FUNCTION() static NetworkObjectRole GetObjectRole(ScriptingObject* obj);
+ API_FUNCTION() static NetworkObjectRole GetObjectRole(const ScriptingObject* obj);
///
/// Checks if the network object is owned locally (thus current client has authority to manage it).
@@ -119,7 +119,7 @@ public:
/// Equivalent to GetObjectRole == OwnedAuthoritative.
/// The network object.
/// True if object is owned by this client, otherwise false.
- API_FUNCTION() FORCE_INLINE static bool IsObjectOwned(ScriptingObject* obj)
+ API_FUNCTION() FORCE_INLINE static bool IsObjectOwned(const ScriptingObject* obj)
{
return GetObjectRole(obj) == NetworkObjectRole::OwnedAuthoritative;
}
@@ -130,7 +130,7 @@ public:
/// Equivalent to GetObjectRole != Replicated.
/// The network object.
/// True if object is simulated on this client, otherwise false.
- API_FUNCTION() FORCE_INLINE static bool IsObjectSimulated(ScriptingObject* obj)
+ API_FUNCTION() FORCE_INLINE static bool IsObjectSimulated(const ScriptingObject* obj)
{
return GetObjectRole(obj) != NetworkObjectRole::Replicated;
}
@@ -141,7 +141,7 @@ public:
/// Equivalent to (GetObjectRole == Replicated or GetObjectRole == ReplicatedAutonomous).
/// The network object.
/// True if object is simulated on this client, otherwise false.
- API_FUNCTION() FORCE_INLINE static bool IsObjectReplicated(ScriptingObject* obj)
+ API_FUNCTION() FORCE_INLINE static bool IsObjectReplicated(const ScriptingObject* obj)
{
const NetworkObjectRole role = GetObjectRole(obj);
return role == NetworkObjectRole::Replicated || role == NetworkObjectRole::ReplicatedSimulated;