Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coordinated Spawns (Purple Edition) #531

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Delayed Spawns don't stop all progress.
  • Loading branch information
MrPurple6411 committed Jan 20, 2024
commit 4644e7754a5da3d98fd9ee74f0f4be7b3343b87c
55 changes: 33 additions & 22 deletions Nautilus/MonoBehaviours/EntitySpawner.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
namespace Nautilus.MonoBehaviours;

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Nautilus.Extensions;
using Nautilus.Handlers;
using Nautilus.Patchers;
using Nautilus.Utility;
using UnityEngine;
using UWE;

namespace Nautilus.MonoBehaviours;

internal class EntitySpawner : MonoBehaviour
{
internal Int3 batchId;
internal IReadOnlyCollection<SpawnInfo> spawnInfos;
internal bool global;
private List<SpawnInfo> delayedSpawns = new List<SpawnInfo>();

private IEnumerator Start()
{
yield return SpawnAsync();
yield return new WaitUntil(() => delayedSpawns.Count == 0);
Destroy(gameObject);
}

Expand All @@ -32,10 +32,7 @@ private IEnumerator SpawnAsync()
// then we wait until the terrain is fully loaded (must be checked on each frame for faster spawns)
yield return new WaitUntil(() => lws.IsBatchReadyToCompile(batchId));
}

var batchCenter = lws.GetBatchCenter(batchId);
var bounds = new Bounds(batchCenter, Vector3.zero);


LargeWorld lw = LargeWorld.main;

yield return new WaitUntil(() => lw != null && lw.streamer.globalRoot != null); // need to make sure global root is ready too for global spawns.
Expand Down Expand Up @@ -70,25 +67,39 @@ private IEnumerator SpawnAsync()
continue;
// 😎 Nice.
}
if (lwe.cellLevel != LargeWorldEntity.CellLevel.Global && lwe.cellLevel != LargeWorldEntity.CellLevel.Batch && !lws.cellManager.AreCellsLoaded(bounds, lwe.cellLevel))

if (lwe.cellLevel < LargeWorldEntity.CellLevel.Batch && !lws.IsRangeActiveAndBuilt(new Bounds(spawnInfo.SpawnPosition, Vector3.one)))
{
// Cells aren't ready yet. We have to wait until they are
yield return new WaitUntil(() => lws.cellManager.AreCellsLoaded(bounds, lwe.cellLevel));
// Cells aren't ready yet. We have to wait until they are.
StartCoroutine(WaitForCellLoaded(lws, prefab, spawnInfo, stringToLog));
continue;
}

GameObject obj = Instantiate(prefab, spawnInfo.SpawnPosition, spawnInfo.Rotation);
obj.transform.localScale = spawnInfo.ActualScale;

obj.SetActive(true);

LargeWorldEntity.Register(obj);

LargeWorldStreamerPatcher.SavedSpawnInfos.Add(spawnInfo);
InternalLogger.Debug($"spawned {stringToLog}.");
Spawn(prefab, spawnInfo, stringToLog);
}
}


private IEnumerator WaitForCellLoaded(LargeWorldStreamer lws, GameObject prefab, SpawnInfo spawnInfo, string stringToLog)
{
delayedSpawns.Add(spawnInfo);
yield return new WaitUntil(() => lws.IsRangeActiveAndBuilt(new Bounds(spawnInfo.SpawnPosition, Vector3.one * 5)));
Spawn(prefab, spawnInfo, stringToLog);
delayedSpawns.Remove(spawnInfo);
}

private void Spawn(GameObject prefab, SpawnInfo spawnInfo, string stringToLog)
{
GameObject obj = Instantiate(prefab, spawnInfo.SpawnPosition, spawnInfo.Rotation);
obj.transform.localScale = spawnInfo.ActualScale;

obj.SetActive(true);

LargeWorldEntity.Register(obj);

LargeWorldStreamerPatcher.SavedSpawnInfos.Add(spawnInfo);
InternalLogger.Debug($"spawned {stringToLog}.");
}

private IEnumerator GetPrefabAsync(SpawnInfo spawnInfo, IOut<GameObject> gameObject)
{
GameObject obj;
Expand Down