public List <Entity> LoadUnspawnedEntities(Int3 batchId) { lock (parsedBatches) { if (parsedBatches.Contains(batchId)) { return(new List <Entity>()); } parsedBatches.Add(batchId); } DeterministicBatchGenerator deterministicBatchGenerator = new DeterministicBatchGenerator(batchId); List <Entity> entities = new List <Entity>(); List <EntitySpawnPoint> spawnPoints = batchCellsParser.ParseBatchData(batchId); entities = SpawnEntities(spawnPoints, deterministicBatchGenerator); if (entities.Count == 0) { lock (emptyBatches) { emptyBatches.Add(batchId); } } else { Log.Info("Spawning " + entities.Count + " entities from " + spawnPoints.Count + " spawn points in batch " + batchId); } return(entities); }
public List <Entity> LoadUnspawnedEntities(Int3 batchId) { lock (parsedBatches) { if (parsedBatches.Contains(batchId)) { return(new List <Entity>()); } parsedBatches.Add(batchId); } DeterministicBatchGenerator deterministicBatchGenerator = new DeterministicBatchGenerator(batchId); List <Entity> entities = new List <Entity>(); List <EntitySpawnPoint> spawnPoints = batchCellsParser.ParseBatchData(batchId); foreach (EntitySpawnPoint esp in spawnPoints) { if (esp.Density > 0) { List <UwePrefab> prefabs = prefabFactory.GetPossiblePrefabs(esp.BiomeType); if (prefabs.Count > 0) { entities.AddRange(SpawnEntitiesUsingRandomDistribution(esp, prefabs, deterministicBatchGenerator)); } else if (esp.ClassId != null) { entities.AddRange(SpawnEntitiesStaticly(esp, deterministicBatchGenerator)); } } } if (entities.Count == 0) { lock (emptyBatches) { emptyBatches.Add(batchId); } } else { Log.Info("Spawning " + entities.Count + " entities from " + spawnPoints.Count + " spawn points in batch " + batchId); } return(entities); }
public List <Entity> LoadUnspawnedEntities(Int3 batchId) { lock (parsedBatches) { if (parsedBatches.Contains(batchId)) { return(new List <Entity>()); } parsedBatches.Add(batchId); } DeterministicBatchGenerator deterministicBatchGenerator = new DeterministicBatchGenerator(batchId); List <Entity> entities = new List <Entity>(); List <EntitySpawnPoint> spawnPoints = batchCellsParser.ParseBatchData(batchId); entities = SpawnEntities(spawnPoints, deterministicBatchGenerator); if (entities.Count == 0) { lock (emptyBatches) { emptyBatches.Add(batchId); } } else { Log.Info("Spawning " + entities.Count + " entities from " + spawnPoints.Count + " spawn points in batch " + batchId); } for (int x = 0; x < entities.Count; x++) // Throws on duplicate Entities already but nice to know which ones { for (int y = 0; y < entities.Count; y++) { if (entities[x] == entities[y] && x != y) { Log.Error("Duplicate Entity detected! " + entities[x]); } } } return(entities); }
private Entity SpawnEntitySlotEntities(NitroxEntitySlot entitySlot, TransformAsset transform, DeterministicBatchGenerator deterministicBatchGenerator, Entity parentEntity) { List <UwePrefab> prefabs = prefabFactory.GetPossiblePrefabs(entitySlot.BiomeType); List <Entity> entities = new List <Entity>(); if (prefabs.Count > 0) { EntitySpawnPoint entitySpawnPoint = new EntitySpawnPoint(parentEntity.AbsoluteEntityCell, transform.LocalPosition, transform.LocalRotation, entitySlot.AllowedTypes.ToList(), 1f, entitySlot.BiomeType); entities.AddRange(SpawnEntitiesUsingRandomDistribution(entitySpawnPoint, prefabs, deterministicBatchGenerator, parentEntity)); } return(entities.FirstOrDefault()); }
private void CreatePrefabPlaceholdersWithChildren(Entity entity, string classId, DeterministicBatchGenerator deterministicBatchGenerator) { List <PrefabAsset> prefabs; // Check to see if this entity is a PrefabPlaceholderGroup. If it is, // we want to add the children that would be spawned here. This is // surpressed on the client so we don't get virtual entities that the // server doesn't know about. if (placeholderPrefabsByGroupClassId.TryGetValue(classId, out prefabs)) { foreach (PrefabAsset prefab in prefabs) { TransformAsset transform = prefab.TransformAsset; Optional <UweWorldEntity> opWorldEntity = worldEntityFactory.From(prefab.ClassId); if (!opWorldEntity.HasValue) { Log.Debug("Unexpected Empty WorldEntity! " + prefab.ClassId); continue; } UweWorldEntity worldEntity = opWorldEntity.Value; Entity prefabEntity = new Entity(transform.LocalPosition, transform.LocalRotation, transform.LocalScale, worldEntity.TechType, worldEntity.CellLevel, prefab.ClassId, true, deterministicBatchGenerator.NextId(), entity); if (prefab.EntitySlot.HasValue) { Entity possibleEntity = SpawnEntitySlotEntities(prefab.EntitySlot.Value, transform, deterministicBatchGenerator, entity); if (possibleEntity != null) { entity.ChildEntities.Add(possibleEntity); } } CreatePrefabPlaceholdersWithChildren(prefabEntity, prefabEntity.ClassId, deterministicBatchGenerator); entity.ChildEntities.Add(prefabEntity); } } }
private List <Entity> SpawnEntities(List <EntitySpawnPoint> entitySpawnPoints, DeterministicBatchGenerator deterministicBatchGenerator, Entity parentEntity = null) { List <Entity> entities = new List <Entity>(); foreach (EntitySpawnPoint esp in entitySpawnPoints) { if (esp.Density > 0) { List <UwePrefab> prefabs = prefabFactory.GetPossiblePrefabs(esp.BiomeType); if (prefabs.Count > 0) { entities.AddRange(SpawnEntitiesUsingRandomDistribution(esp, prefabs, deterministicBatchGenerator, parentEntity)); } else if (esp.ClassId != null) { entities.AddRange(SpawnEntitiesStaticly(esp, deterministicBatchGenerator, parentEntity)); } } } return(entities); }
private IEnumerable <Entity> CreateEntityWithChildren(EntitySpawnPoint entitySpawnPoint, Vector3 scale, TechType techType, int cellLevel, string classId, DeterministicBatchGenerator deterministicBatchGenerator, Entity parentEntity = null) { Entity spawnedEntity = new Entity(entitySpawnPoint.LocalPosition, entitySpawnPoint.LocalRotation, scale, techType, cellLevel, classId, true, deterministicBatchGenerator.NextId(), parentEntity); spawnedEntity.ChildEntities = SpawnEntities(entitySpawnPoint.Children, deterministicBatchGenerator, spawnedEntity); CreatePrefabPlaceholdersWithChildren(spawnedEntity, classId, deterministicBatchGenerator); IEntityBootstrapper bootstrapper; if (customBootstrappersByTechType.TryGetValue(techType, out bootstrapper)) { bootstrapper.Prepare(spawnedEntity, deterministicBatchGenerator); } yield return(spawnedEntity); if (parentEntity == null) // Ensures children are only returned at the top level { // Children are yielded as well so they can be indexed at the top level (for use by simulation // ownership and various other consumers). The parent should always be yielded before the children foreach (Entity childEntity in AllChildren(spawnedEntity)) { yield return(childEntity); } } }
private IEnumerable <Entity> SpawnEntitiesStaticly(EntitySpawnPoint entitySpawnPoint, DeterministicBatchGenerator deterministicBatchGenerator, Entity parentEntity = null) { Optional <UweWorldEntity> uweWorldEntity = worldEntityFactory.From(entitySpawnPoint.ClassId); if (uweWorldEntity.HasValue) { IEnumerable <Entity> entities = CreateEntityWithChildren(entitySpawnPoint, entitySpawnPoint.Scale, uweWorldEntity.Value.TechType, uweWorldEntity.Value.CellLevel, entitySpawnPoint.ClassId, deterministicBatchGenerator, parentEntity); foreach (Entity entity in entities) { yield return(entity); } } }
private IEnumerable <Entity> SpawnEntitiesUsingRandomDistribution(EntitySpawnPoint entitySpawnPoint, List <UwePrefab> prefabs, DeterministicBatchGenerator deterministicBatchGenerator, Entity parentEntity = null) { List <UwePrefab> allowedPrefabs = FilterAllowedPrefabs(prefabs, entitySpawnPoint); float rollingProbabilityDensity = allowedPrefabs.Sum(prefab => prefab.Probability / entitySpawnPoint.Density); if (rollingProbabilityDensity <= 0) { yield break; } double randomNumber = deterministicBatchGenerator.NextDouble(); if (rollingProbabilityDensity > 1f) { randomNumber *= rollingProbabilityDensity; } double rollingProbability = 0; UwePrefab selectedPrefab = allowedPrefabs.FirstOrDefault(prefab => { if (Math.Abs(prefab.Probability) < 0.0001) { return(false); } float probabilityDensity = prefab.Probability / entitySpawnPoint.Density; rollingProbability += probabilityDensity; return(rollingProbability >= randomNumber); }); if (selectedPrefab == null) { yield break; } Optional <UweWorldEntity> opWorldEntity = worldEntityFactory.From(selectedPrefab.ClassId); if (opWorldEntity.HasValue) { UweWorldEntity uweWorldEntity = opWorldEntity.Value; for (int i = 0; i < selectedPrefab.Count; i++) { IEnumerable <Entity> entities = CreateEntityWithChildren(entitySpawnPoint, uweWorldEntity.Scale, uweWorldEntity.TechType, uweWorldEntity.CellLevel, selectedPrefab.ClassId, deterministicBatchGenerator, parentEntity); foreach (Entity entity in entities) { yield return(entity); } } } }
// Entities that have been spawned by a parent prefab (child game objects baked into the prefab). // created separately as we don't actually want to spawn these but instead just update the id. // will refactor this piece a bit later to split these into a new data structure. private List <Entity> ConvertComponentPrefabsToEntities(List <PrefabAsset> prefabs, Entity parent, DeterministicBatchGenerator deterministicBatchGenerator) { List <Entity> entities = new List <Entity>(); int counter = 0; foreach (PrefabAsset prefab in prefabs) { TransformAsset transform = prefab.TransformAsset; Entity prefabEntity = new Entity(transform.LocalPosition, transform.LocalRotation, transform.LocalScale, new NitroxTechType("None"), 1, prefab.ClassId, true, deterministicBatchGenerator.NextId(), counter++, parent); prefabEntity.ChildEntities = ConvertComponentPrefabsToEntities(prefab.Children, prefabEntity, deterministicBatchGenerator); entities.Add(prefabEntity); } return(entities); }
// Entities that have been spawned by a parent prefab (child game objects baked into the prefab). // created separately as we don't actually want to spawn these but instead just update the id. // will refactor this piece a bit later to split these into a new data structure. private List <Entity> ConvertComponentPrefabsToEntities(List <PrefabAsset> prefabs, Entity parent, DeterministicBatchGenerator deterministicBatchGenerator, ref List <PrefabAsset> spawnablePrefabs) { List <Entity> entities = new List <Entity>(); int counter = 0; foreach (PrefabAsset prefab in prefabs) { TransformAsset transform = prefab.TransformAsset; Entity prefabEntity = new Entity(transform.LocalPosition, transform.LocalRotation, transform.LocalScale, new NitroxTechType("None"), 1, prefab.ClassId, true, deterministicBatchGenerator.NextId(), counter++, parent); // Checkes if the current object being setup is a Placeholder object. // MrPurple6411 Verified All Placeholders use this in the name. (verified in SN1 did not check BZ yet) if (prefab.Name.Contains("(Placeholder)")) { // Finds the matching prefab that the placeholder is supposed to spawn. PrefabAsset spawnablePrefab = spawnablePrefabs.Find((x) => x.TransformAsset == transform); if (spawnablePrefab != null) { Optional <UweWorldEntity> opWorldEntity = worldEntityFactory.From(spawnablePrefab.ClassId); if (!opWorldEntity.HasValue) { Log.Debug($"Unexpected Empty WorldEntity! {spawnablePrefab.Name}-{spawnablePrefab.ClassId}"); continue; } UweWorldEntity worldEntity = opWorldEntity.Value; Entity spawnableprefabEntity = new Entity(transform.LocalPosition, transform.LocalRotation, transform.LocalScale, worldEntity.TechType, worldEntity.CellLevel, spawnablePrefab.ClassId, true, deterministicBatchGenerator.NextId(), null, parent); if (spawnablePrefab.EntitySlot.HasValue) { Entity possibleEntity = SpawnEntitySlotEntities(spawnablePrefab.EntitySlot.Value, transform, deterministicBatchGenerator, parent); if (possibleEntity != null) { parent.ChildEntities.Add(possibleEntity); } } // Setup any children this object may have attached to it. CreatePrefabPlaceholdersWithChildren(spawnableprefabEntity, spawnableprefabEntity.ClassId, deterministicBatchGenerator); // Add the object to the child list that that is being returned by this method. entities.Add(spawnableprefabEntity); // remove prefab from placeholder list so it is not duplicated later by mistake. spawnablePrefabs.Remove(spawnablePrefab); } else { Log.Error($"Unable to find matching spawnable prefab for Placeholder {prefab.Name}"); } } prefabEntity.ChildEntities = ConvertComponentPrefabsToEntities(prefab.Children, prefabEntity, deterministicBatchGenerator, ref spawnablePrefabs); entities.Add(prefabEntity); } return(entities); }
private IEnumerable <Entity> CreateEntityWithChildren(EntitySpawnPoint entitySpawnPoint, TechType techType, LargeWorldEntity.CellLevel cellLevel, string classId, DeterministicBatchGenerator deterministicBatchGenerator) { Entity spawnedEntity = new Entity(entitySpawnPoint.Position, entitySpawnPoint.Rotation, entitySpawnPoint.Scale, techType, (int)cellLevel, classId, true, deterministicBatchGenerator.NextGuid()); yield return(spawnedEntity); IEntityBootstrapper bootstrapper; if (customBootstrappersByTechType.TryGetValue(spawnedEntity.TechType, out bootstrapper)) { bootstrapper.Prepare(spawnedEntity, deterministicBatchGenerator); foreach (Entity childEntity in spawnedEntity.ChildEntities) { yield return(childEntity); } } }
private IEnumerable <Entity> SpawnEntitiesStaticly(EntitySpawnPoint entitySpawnPoint, DeterministicBatchGenerator deterministicBatchGenerator) { WorldEntityInfo worldEntityInfo; if (worldEntitiesByClassId.TryGetValue(entitySpawnPoint.ClassId, out worldEntityInfo)) { IEnumerable <Entity> entities = CreateEntityWithChildren(entitySpawnPoint, worldEntityInfo.techType, worldEntityInfo.cellLevel, entitySpawnPoint.ClassId, deterministicBatchGenerator); foreach (Entity entity in entities) { yield return(entity); } } }
private IEnumerable <Entity> SpawnEntitiesUsingRandomDistribution(EntitySpawnPoint entitySpawnPoint, DstData dstData, DeterministicBatchGenerator deterministicBatchGenerator) { List <PrefabData> allowedPrefabs = filterAllowedPrefabs(dstData.prefabs, entitySpawnPoint); float rollingProbabilityDensity = allowedPrefabs.Sum(prefab => prefab.probability / entitySpawnPoint.Density); if (rollingProbabilityDensity <= 0) { yield break; } double randomNumber = deterministicBatchGenerator.NextDouble(); if (rollingProbabilityDensity > 1f) { randomNumber *= rollingProbabilityDensity; } double rollingProbability = 0; PrefabData selectedPrefab = allowedPrefabs.FirstOrDefault(prefab => { if (prefab.probability == 0) { return(false); } float probabilityDensity = prefab.probability / entitySpawnPoint.Density; rollingProbability += probabilityDensity; return(rollingProbability >= randomNumber); }); WorldEntityInfo worldEntityInfo; if (!ReferenceEquals(selectedPrefab, null) && worldEntitiesByClassId.TryGetValue(selectedPrefab.classId, out worldEntityInfo)) { for (int i = 0; i < selectedPrefab.count; i++) { IEnumerable <Entity> entities = CreateEntityWithChildren(entitySpawnPoint, worldEntityInfo.techType, worldEntityInfo.cellLevel, selectedPrefab.classId, deterministicBatchGenerator); foreach (Entity entity in entities) { yield return(entity); } } } }
private void AssignPlaceholderEntitiesIfRequired(Entity entity, TechType techType, int cellLevel, string classId, DeterministicBatchGenerator deterministicBatchGenerator) { List <PrefabAsset> prefabs; // Check to see if this entity is a PrefabPlaceholderGroup. If it is, // we want to add the children that would be spawned here. This is // surpressed on the client so we don't get virtual entities that the // server doesn't know about. if (placeholderPrefabsByGroupClassId.TryGetValue(classId, out prefabs)) { foreach (PrefabAsset prefab in prefabs) { TransformAsset transform = prefab.TransformAsset; Vector3 position = transform.Position + entity.Position; Entity prefabEntity = new Entity(position, transform.Rotation, transform.Scale, techType, cellLevel, prefab.ClassId, true, deterministicBatchGenerator.NextGuid()); entity.ChildEntities.Add(prefabEntity); } } }
private IEnumerable <Entity> CreateEntityWithChildren(EntitySpawnPoint entitySpawnPoint, UnityEngine.Vector3 scale, TechType techType, int cellLevel, string classId, DeterministicBatchGenerator deterministicBatchGenerator) { Entity spawnedEntity = new Entity(entitySpawnPoint.Position, entitySpawnPoint.Rotation, scale, techType, cellLevel, classId, true, deterministicBatchGenerator.NextGuid()); yield return(spawnedEntity); AssignPlaceholderEntitiesIfRequired(spawnedEntity, techType, cellLevel, classId, deterministicBatchGenerator); IEntityBootstrapper bootstrapper; if (customBootstrappersByTechType.TryGetValue(techType, out bootstrapper)) { bootstrapper.Prepare(spawnedEntity, deterministicBatchGenerator); } // Children are yielded as well so they can be indexed at the top level (for use by simulation // ownership and various other consumers). The parent should always be yielded before the children foreach (Entity childEntity in spawnedEntity.ChildEntities) { yield return(childEntity); } }