private IEnumerable <Entity> SpawnEntitiesUsingRandomDistribution(EntitySpawnPoint entitySpawnPoint, List <UwePrefab> prefabs, DeterministicBatchGenerator deterministicBatchGenerator) { 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 (prefab.Probability == 0) { 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.IsPresent()) { UweWorldEntity uweWorldEntity = opWorldEntity.Get(); for (int i = 0; i < selectedPrefab.Count; i++) { IEnumerable <Entity> entities = CreateEntityWithChildren(entitySpawnPoint, uweWorldEntity.Scale, uweWorldEntity.TechType, uweWorldEntity.CellLevel, selectedPrefab.ClassId, deterministicBatchGenerator); foreach (Entity entity in entities) { yield return(entity); } } } }
private void CreatePrefabPlaceholdersWithChildren(Entity entity, string classId, DeterministicBatchGenerator deterministicBatchGenerator) { PrefabPlaceholdersGroupAsset group; // 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 (prefabPlaceholderGroupsbyClassId.TryGetValue(classId, out group)) { foreach (PrefabAsset prefab in group.SpawnablePrefabs) { 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(), null, 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); } entity.ChildEntities.AddRange(ConvertComponentPrefabsToEntities(group.ExistingPrefabs, entity, deterministicBatchGenerator)); } }
public override Optional <UweWorldEntity> From(string classId) { if (worldEntitiesByClassId.TryGetValue(classId, out WorldEntityInfo worldEntityInfo)) { UweWorldEntity uweWorldEntity = new UweWorldEntity(worldEntityInfo.techType.ToDto(), worldEntityInfo.localScale.ToDto(), worldEntityInfo.classId, worldEntityInfo.slotType.ToString(), (int)worldEntityInfo.cellLevel); return(Optional.Of(uweWorldEntity)); } return(Optional.Empty); }
private void AssignPlaceholderEntitiesIfRequired(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.IsEmpty()) { Log.Debug("Unexpected Empty WorldEntity! " + prefab.ClassId); continue; } UweWorldEntity worldEntity = opWorldEntity.Get(); Entity prefabEntity = new Entity(transform.LocalPosition, transform.LocalRotation, transform.LocalScale, worldEntity.TechType, worldEntity.CellLevel, prefab.ClassId, true, deterministicBatchGenerator.NextId(), entity); entity.ChildEntities.Add(prefabEntity); } } }
// 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); }