Skip to content

Commit

Permalink
Add an Instantiate wrapper to include the NitroxEntity in spawned obj…
Browse files Browse the repository at this point in the history
…ects before its components are enabled, override UniqueIdentifier's id by NitroxEntity's id, implement more sync spawners
  • Loading branch information
tornac1234 committed Nov 7, 2023
1 parent 78322c1 commit 246e866
Show file tree
Hide file tree
Showing 15 changed files with 136 additions and 86 deletions.
13 changes: 6 additions & 7 deletions NitroxClient/GameLogic/Spawning/InstalledBatteryEntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using NitroxClient.GameLogic.Spawning.Abstract;
using NitroxClient.GameLogic.Spawning.WorldEntities;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.Util;
Expand All @@ -25,9 +26,9 @@ protected override IEnumerator SpawnAsync(InstalledBatteryEntity entity, TaskRes

TaskResult<GameObject> prefabResult = new();
yield return DefaultWorldEntitySpawner.RequestPrefab(entity.TechType.ToUnity(), prefabResult);
GameObject gameObject = UnityEngine.Object.Instantiate(prefabResult.Get());
GameObject gameObject = GameObjectHelper.InstantiateWithId(prefabResult.Get(), entity.Id);

SetupObject(entity, gameObject, energyMixin);
SetupObject(gameObject, energyMixin);

result.Set(gameObject);
}
Expand All @@ -44,9 +45,9 @@ protected override bool SpawnSync(InstalledBatteryEntity entity, TaskResult<Opti
return true;
}

GameObject gameObject = Utils.SpawnFromPrefab(prefab, null);
GameObject gameObject = GameObjectHelper.SpawnFromPrefab(prefab, entity.Id);

SetupObject(entity, gameObject, energyMixin);
SetupObject(gameObject, energyMixin);

result.Set(gameObject);
return true;
Expand Down Expand Up @@ -74,13 +75,11 @@ private bool CanSpawn(Entity entity, out EnergyMixin energyMixin, out string err
return true;
}

private void SetupObject(Entity entity, GameObject gameObject, EnergyMixin energyMixin)
private void SetupObject(GameObject gameObject, EnergyMixin energyMixin)
{
energyMixin.Initialize();
energyMixin.RestoreBattery();

NitroxEntity.SetNewId(gameObject, entity.Id);

using (PacketSuppressor<EntityReparented>.Suppress())
using (PacketSuppressor<EntitySpawnedByClient>.Suppress())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected override IEnumerator SpawnAsync(InstalledModuleEntity entity, TaskResu
}

TaskResult<GameObject> gameObjectResult = new();
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, gameObjectResult);
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, entity.Id, gameObjectResult);
GameObject gameObject = gameObjectResult.Get();

SetupObject(entity, gameObject, parentObject, equipment);
Expand All @@ -43,7 +43,7 @@ protected override bool SpawnSync(InstalledModuleEntity entity, TaskResult<Optio
return true;
}

GameObject gameObject = Utils.SpawnFromPrefab(prefab, null);
GameObject gameObject = GameObjectHelper.SpawnFromPrefab(prefab, entity.Id);

SetupObject(entity, gameObject, parentObject, equipment);

Expand Down Expand Up @@ -77,8 +77,6 @@ private bool CanSpawn(InstalledModuleEntity entity, out GameObject parentObject,

private void SetupObject(InstalledModuleEntity entity, GameObject gameObject, GameObject parentObject, Equipment equipment)
{
NitroxEntity.SetNewId(gameObject, entity.Id);

Pickupable pickupable = gameObject.RequireComponent<Pickupable>();
pickupable.Initialize();

Expand Down
11 changes: 8 additions & 3 deletions NitroxClient/GameLogic/Spawning/InventoryEntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@

namespace NitroxClient.GameLogic.Spawning;

public class InventoryEntitySpawner : EntitySpawner<InventoryEntity>
public class InventoryEntitySpawner : SyncEntitySpawner<InventoryEntity>
{
protected override IEnumerator SpawnAsync(InventoryEntity entity, TaskResult<Optional<GameObject>> result)
{
SpawnSync(entity, result);
yield break;
}

protected override bool SpawnSync(InventoryEntity entity, TaskResult<Optional<GameObject>> result)
{
GameObject parent = NitroxEntity.RequireObjectFrom(entity.ParentId);
StorageContainer container = parent.GetAllComponentsInChildren<StorageContainer>()
Expand All @@ -26,8 +32,7 @@ protected override IEnumerator SpawnAsync(InventoryEntity entity, TaskResult<Opt
Log.Error($"Unable to find {nameof(StorageContainer)} for: {entity}");
result.Set(Optional.Empty);
}

yield break;
return true;
}

protected override bool SpawnsOwnChildren(InventoryEntity entity) => false;
Expand Down
6 changes: 2 additions & 4 deletions NitroxClient/GameLogic/Spawning/InventoryItemEntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ protected override IEnumerator SpawnAsync(InventoryItemEntity entity, TaskResult
}

TaskResult<GameObject> gameObjectResult = new();
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, gameObjectResult);
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, entity.Id, gameObjectResult);
GameObject gameObject = gameObjectResult.Get();

SetupObject(entity, gameObject, parentObject, container);
Expand All @@ -45,7 +45,7 @@ protected override bool SpawnSync(InventoryItemEntity entity, TaskResult<Optiona
return true;
}

GameObject gameObject = Utils.SpawnFromPrefab(prefab, null);
GameObject gameObject = GameObjectHelper.SpawnFromPrefab(prefab, entity.Id);

SetupObject(entity, gameObject, parentObject, container);

Expand Down Expand Up @@ -84,8 +84,6 @@ private bool CanSpawn(InventoryItemEntity entity, out GameObject parentObject, o

private void SetupObject(InventoryItemEntity entity, GameObject gameObject, GameObject parentObject, ItemsContainer container)
{
NitroxEntity.SetNewId(gameObject, entity.Id);

Pickupable pickupable = gameObject.RequireComponent<Pickupable>();
pickupable.Initialize();

Expand Down
13 changes: 10 additions & 3 deletions NitroxClient/GameLogic/Spawning/PathBasedChildEntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@

namespace NitroxClient.GameLogic.Spawning;

public class PathBasedChildEntitySpawner : EntitySpawner<PathBasedChildEntity>
public class PathBasedChildEntitySpawner : SyncEntitySpawner<PathBasedChildEntity>
{
protected override IEnumerator SpawnAsync(PathBasedChildEntity entity, TaskResult<Optional<GameObject>> result)
{
SpawnSync(entity, result);
yield break;
}

protected override bool SpawnSync(PathBasedChildEntity entity, TaskResult<Optional<GameObject>> result)
{
Optional<GameObject> owner = NitroxEntity.GetObjectFrom(entity.ParentId);

if (!owner.HasValue)
{
Log.Error($"Unable to find parent entity: {entity}");
result.Set(Optional.Empty);
yield break;
return true;
}

Transform child = owner.Value.transform.Find(entity.Path);
Expand All @@ -26,13 +32,14 @@ protected override IEnumerator SpawnAsync(PathBasedChildEntity entity, TaskResul
{
Log.Error($"Could not locate child at path {entity.Path} in {owner.Value.name}");
result.Set(Optional.Empty);
yield break;
return true;
}

GameObject gameObject = child.gameObject;
NitroxEntity.SetNewId(gameObject, entity.Id);

result.Set(gameObject);
return true;
}

protected override bool SpawnsOwnChildren(PathBasedChildEntity entity) => false;
Expand Down
11 changes: 8 additions & 3 deletions NitroxClient/GameLogic/Spawning/PrefabChildEntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@

namespace NitroxClient.GameLogic.Spawning;

public class PrefabChildEntitySpawner : EntitySpawner<PrefabChildEntity>
public class PrefabChildEntitySpawner : SyncEntitySpawner<PrefabChildEntity>
{
// When we encounter a PrefabChildEntity, we need to assign the id to a prefab with the same class id and index.
protected override IEnumerator SpawnAsync(PrefabChildEntity entity, TaskResult<Optional<GameObject>> result)
{
SpawnSync(entity, result);
yield break;
}

protected override bool SpawnSync(PrefabChildEntity entity, TaskResult<Optional<GameObject>> result)
{
GameObject parent = NitroxEntity.RequireObjectFrom(entity.ParentId);
PrefabIdentifier prefab = parent.GetAllComponentsInChildren<PrefabIdentifier>()
Expand All @@ -28,8 +34,7 @@ protected override IEnumerator SpawnAsync(PrefabChildEntity entity, TaskResult<O
Log.Error($"Unable to find prefab for: {entity}");
result.Set(Optional.Empty);
}

yield break;
return true;
}

protected override bool SpawnsOwnChildren(PrefabChildEntity entity) => false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.Util;
Expand All @@ -21,12 +20,10 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional<GameObject> parent, E
{
CrashHome crashHome = parent.Value.GetComponent<CrashHome>();

GameObject gameObject = GameObject.Instantiate(crashHome.crashPrefab, Vector3.zero, spawnRotation);
GameObject gameObject = GameObjectHelper.InstantiateWithId(crashHome.crashPrefab, entity.Id, rotation: spawnRotation);
gameObject.transform.SetParent(crashHome.transform, false);
crashHome.crash = gameObject.GetComponent<Crash>();
crashHome.spawnTime = -1;

NitroxEntity.SetNewId(gameObject, entity.Id);
}

result.Set(Optional.Empty);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using NitroxClient.MonoBehaviours;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.Util;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;
using UWE;
using static NitroxClient.Unity.Helper.GameObjectHelper;

namespace NitroxClient.GameLogic.Spawning.WorldEntities;

Expand All @@ -20,7 +21,7 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional<GameObject> parent, E
TechType techType = entity.TechType.ToUnity();

TaskResult<GameObject> gameObjectResult = new();
yield return CreateGameObject(techType, entity.ClassId, gameObjectResult);
yield return CreateGameObject(techType, entity.ClassId, entity.Id, gameObjectResult);

GameObject gameObject = gameObjectResult.Get();
SetupObject(entity, parent, gameObject, cellRoot, techType);
Expand All @@ -34,7 +35,6 @@ private void SetupObject(WorldEntity entity, Optional<GameObject> parent, GameOb
gameObject.transform.rotation = entity.Transform.Rotation.ToUnity();
gameObject.transform.localScale = entity.Transform.LocalScale.ToUnity();

NitroxEntity.SetNewId(gameObject, entity.Id);
CrafterLogic.NotifyCraftEnd(gameObject, techType);

WaterPark parentWaterPark = parent.HasValue ? parent.Value.GetComponent<WaterPark>() : null;
Expand Down Expand Up @@ -119,7 +119,7 @@ public static IEnumerator RequestPrefab(string classId, TaskResult<GameObject> r
result.Set(prefab);
}

public static IEnumerator CreateGameObject(TechType techType, string classId, TaskResult<GameObject> result)
public static IEnumerator CreateGameObject(TechType techType, string classId, NitroxId nitroxId, TaskResult<GameObject> result)
{
IPrefabRequest prefabCoroutine = PrefabDatabase.GetPrefabAsync(classId);
yield return prefabCoroutine;
Expand All @@ -134,7 +134,7 @@ public static IEnumerator CreateGameObject(TechType techType, string classId, Ta
prefab = techPrefabCoroutine.GetResult();
if (!prefab)
{
result.Set(Utils.CreateGenericLoot(techType));
result.Set(CreateGenericLoot(techType, nitroxId));
prefabNotFound.Add((classId, techType));
yield break;
}
Expand All @@ -144,22 +144,22 @@ public static IEnumerator CreateGameObject(TechType techType, string classId, Ta
}
}

result.Set(Utils.SpawnFromPrefab(prefab, null));
result.Set(SpawnFromPrefab(prefab, nitroxId));
}

/// <summary>
/// Looks in prefab cache and creates a GameObject out of it if possible, or returns false.
/// </summary>
public static bool TryCreateGameObjectSync(TechType techType, string classId, out GameObject gameObject)
public static bool TryCreateGameObjectSync(TechType techType, string classId, NitroxId nitroxId, out GameObject gameObject)
{
if (prefabNotFound.Contains((classId, techType)))
{
gameObject = Utils.CreateGenericLoot(techType);
gameObject = CreateGenericLoot(techType, nitroxId);
return true;
}
else if (TryGetCachedPrefab(out GameObject prefab, techType, classId))
{
gameObject = Utils.SpawnFromPrefab(prefab, null);
gameObject = SpawnFromPrefab(prefab, nitroxId);
return true;
}
gameObject = null;
Expand All @@ -170,7 +170,7 @@ public bool SpawnSync(WorldEntity entity, Optional<GameObject> parent, EntityCel
{
TechType techType = entity.TechType.ToUnity();

if (TryCreateGameObjectSync(techType, entity.ClassId, out GameObject gameObject))
if (TryCreateGameObjectSync(techType, entity.ClassId, entity.Id, out GameObject gameObject))
{
SetupObject(entity, parent, gameObject, cellRoot, techType);
result.Set(gameObject);
Expand All @@ -180,8 +180,5 @@ public bool SpawnSync(WorldEntity entity, Optional<GameObject> parent, EntityCel
return false;
}

public bool SpawnsOwnChildren()
{
return false;
}
public bool SpawnsOwnChildren() => false;
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
using System.Collections;
using NitroxClient.GameLogic.Spawning.Abstract;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.Util;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;

namespace NitroxClient.GameLogic.Spawning.WorldEntities;

public class GlobalRootEntitySpawner : EntitySpawner<GlobalRootEntity>
public class GlobalRootEntitySpawner : SyncEntitySpawner<GlobalRootEntity>
{
// TODO: Add a sync entity spawner
protected override IEnumerator SpawnAsync(GlobalRootEntity entity, TaskResult<Optional<GameObject>> result)
{
TaskResult<GameObject> gameObjectResult = new();
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, gameObjectResult);
yield return DefaultWorldEntitySpawner.CreateGameObject(entity.TechType.ToUnity(), entity.ClassId, entity.Id, gameObjectResult);
GameObject gameObject = gameObjectResult.Get();
NitroxEntity.SetNewId(gameObject, entity.Id);

SetupObject(entity, gameObject);

result.Set(gameObject);
}

protected override bool SpawnSync(GlobalRootEntity entity, TaskResult<Optional<GameObject>> result)
{
if (!DefaultWorldEntitySpawner.TryGetCachedPrefab(out GameObject prefab, entity.TechType.ToUnity(), entity.ClassId))
{
return false;
}
GameObject gameObject = GameObjectHelper.InstantiateWithId(prefab, entity.Id);
SetupObject(entity, gameObject);

result.Set(gameObject);
return true;
}

private void SetupObject(GlobalRootEntity entity, GameObject gameObject)
{
LargeWorldEntity largeWorldEntity = gameObject.EnsureComponent<LargeWorldEntity>();
largeWorldEntity.cellLevel = LargeWorldEntity.CellLevel.Global;
LargeWorld.main.streamer.cellManager.RegisterEntity(largeWorldEntity);
Expand All @@ -33,8 +52,6 @@ protected override IEnumerator SpawnAsync(GlobalRootEntity entity, TaskResult<Op
{
PlacedWorldEntitySpawner.AdditionalSpawningSteps(gameObject);
}

result.Set(Optional.Of(gameObject));
}

protected override bool SpawnsOwnChildren(GlobalRootEntity entity) => false;
Expand Down
Loading

0 comments on commit 246e866

Please sign in to comment.