private static void ApplyWorldSpawnerTemplates(List <SpawnSystemList> spawnLists) { var templates = WorldSpawnTemplateManager .GetTemplates() .Where(x => x.template.TemplateEnabled) .OrderBy(x => x.id) .ToList(); Log.LogTrace($"Found {templates.Count} world spawner templates to apply."); if (templates.Count == 0) { return; } var spawners = spawnLists .SelectMany(x => x.m_spawners) .ToList(); var mainSpawnList = spawnLists.FirstOrDefault(); if (mainSpawnList.IsNull()) { Log.LogWarning("Something is really wrong. No SpawnSystemLists found. Skipping configuration of world spawners."); return; } foreach ((int id, WorldSpawnTemplate template) in templates) { // Validate if (!template.TemplateEnabled) { continue; } SpawnSystem.SpawnData entry; if (ConfigurationManager.GeneralConfig?.AlwaysAppend?.Value == true || id >= spawners.Count) { entry = new SpawnSystem.SpawnData(); mainSpawnList.m_spawners.Add(entry); Log.LogTrace($"Creating spawner entry for template [{id}:{template.PrefabName}]"); ConfigureNewEntry(entry, template); } else { Log.LogTrace($"Overriding spawner entry [{id}:{spawners[id].m_prefab.name}] with template '{template.TemplateName}'"); entry = spawners[id]; ConfigureExistingEntry(entry, template); } WorldSpawnerManager.SetTemplate(entry, template); } }
[HarmonyPriority(Priority.LowerThanNormal)] // Let other prefixes do what they want first. private static bool DelayUpdate(SpawnSystem __instance, bool eventSpawners) { // Ignore event spawners. Let them do what they do. if (eventSpawners) { return(true); } return(!WorldSpawnerManager.ShouldDelaySpawnerUpdate(__instance)); }
private static void InitSpawner(SpawnSystem __instance) { try { WorldSpawnerManager.ConfigureSpawnList(__instance); WorldSpawnSessionManager.StartSession(__instance); } catch (Exception e) { Log.LogError("Error during Spawn That world spawner init", e); } }
public static void StartSpawnSession(SpawnSystem.SpawnData currentEntry) { try { #if DEBUG && VERBOSE Log.LogDebug("WorldSpawnSessionManager.StartSpawnSession"); #endif SpawnDataEntry = currentEntry; SpawnTemplate = WorldSpawnerManager.GetTemplate(SpawnDataEntry); } catch (Exception e) { Log.LogError("Error during initialization of spawner entry session.", e); } }
private static void SetInstantiated(SpawnSystem __instance) { WorldSpawnerManager.EnsureInstantiatedSpawnListAssigned(__instance); }
private static void PrefabCacher() { WorldSpawnerManager.SetPrefabSpawnSystemLists(); }
internal static List <string> WriteSpawner(SpawnSystem.SpawnData spawner, int index, bool postChange) { List <string> lines = new List <string>(); // Try get template. var template = WorldSpawnerManager.GetTemplate(spawner); //Write header if (template is not null) { lines.Add($"[WorldSpawner.{template.Index}]"); } else { lines.Add($"[WorldSpawner.{index}]"); } string environmentArray = ""; try { if ((spawner.m_requiredEnvironments?.Count ?? 0) > 0) { environmentArray = spawner.m_requiredEnvironments.Join(); } } catch (Exception e) { Log.LogWarning($"Error while attempting to read required environments of spawner {spawner}", e); } //Write lines lines.Add($"{nameof(SpawnConfiguration.Name)}={spawner.m_name}"); lines.Add($"{nameof(SpawnConfiguration.Enabled)}={spawner.m_enabled}"); try { lines.Add($"{nameof(SpawnConfiguration.Biomes)}={BiomeArray(spawner.m_biome)}"); } catch (Exception e) { Log.LogWarning($"Failed to read biome of {spawner}", e); } try { lines.Add($"{nameof(SpawnConfiguration.PrefabName)}={spawner.m_prefab.GetCleanedName()}"); } catch (Exception e) { Log.LogWarning($"Error while attempting to read name of prefab for world spawn {spawner?.m_name}, to print to debug file.", e); } lines.Add($"{nameof(SpawnConfiguration.HuntPlayer)}={spawner.m_huntPlayer}"); lines.Add($"{nameof(SpawnConfiguration.MaxSpawned)}={spawner.m_maxSpawned}"); lines.Add($"{nameof(SpawnConfiguration.SpawnInterval)}={spawner.m_spawnInterval.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnChance)}={spawner.m_spawnChance.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.LevelMin)}={spawner.m_minLevel}"); lines.Add($"{nameof(SpawnConfiguration.LevelMax)}={spawner.m_maxLevel}"); lines.Add($"{nameof(SpawnConfiguration.LevelUpMinCenterDistance)}={spawner.m_levelUpMinCenterDistance.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnDistance)}={spawner.m_spawnDistance.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnRadiusMin)}={spawner.m_spawnRadiusMin.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnRadiusMax)}={spawner.m_spawnRadiusMax.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.RequiredGlobalKey)}={spawner.m_requiredGlobalKey}"); lines.Add($"{nameof(SpawnConfiguration.RequiredEnvironments)}={environmentArray}"); lines.Add($"{nameof(SpawnConfiguration.GroupSizeMin)}={spawner.m_groupSizeMin}"); lines.Add($"{nameof(SpawnConfiguration.GroupSizeMax)}={spawner.m_groupSizeMax}"); lines.Add($"{nameof(SpawnConfiguration.GroupRadius)}={spawner.m_groupRadius.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.GroundOffset)}={spawner.m_groundOffset.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnDuringDay)}={spawner.m_spawnAtDay}"); lines.Add($"{nameof(SpawnConfiguration.SpawnDuringNight)}={spawner.m_spawnAtNight}"); lines.Add($"{nameof(SpawnConfiguration.ConditionAltitudeMin)}={spawner.m_minAltitude.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.ConditionAltitudeMax)}={spawner.m_maxAltitude.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.ConditionTiltMin)}={spawner.m_minTilt.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.ConditionTiltMax)}={spawner.m_maxTilt.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.SpawnInForest)}={spawner.m_inForest}"); lines.Add($"{nameof(SpawnConfiguration.SpawnOutsideForest)}={spawner.m_outsideForest}"); lines.Add($"{nameof(SpawnConfiguration.OceanDepthMin)}={spawner.m_minOceanDepth.ToString(CultureInfo.InvariantCulture)}"); lines.Add($"{nameof(SpawnConfiguration.OceanDepthMax)}={spawner.m_maxOceanDepth.ToString(CultureInfo.InvariantCulture)}"); try { if (template is null) { Character character = spawner.m_prefab.IsNull() ? null : spawner.m_prefab.GetComponent <Character>(); string factionName = ""; if (character.IsNotNull()) { factionName = character.m_faction.ToString(); } lines.Add($"{nameof(SpawnConfiguration.SetFaction)}={factionName}"); } } catch (Exception e) { Log.LogWarning($"Error while attempting to write faction of spawner {spawner}", e); } HashSet <Type> AddedOptions = new(); if (template is not null) { // Add custom settings. foreach (var condition in template.SpawnConditions) { switch (condition) { case ConditionDistanceToCenter con: if (AddedOptions.Add(con.GetType())) { if ((con.MinDistance ?? 0) != 0) { lines.Add($"{nameof(SpawnConfiguration.ConditionDistanceToCenterMin)}={(con.MinDistance ?? 0).ToString(CultureInfo.InvariantCulture)}"); } if ((con.MaxDistance ?? 0) != 0) { lines.Add($"{nameof(SpawnConfiguration.ConditionDistanceToCenterMax)}={(con.MaxDistance ?? 0).ToString(CultureInfo.InvariantCulture)}"); } } break; case ConditionWorldAge con: if (AddedOptions.Add(con.GetType())) { if ((con.MinDays ?? 0) != 0) { lines.Add($"{nameof(SpawnConfiguration.ConditionWorldAgeDaysMin)}={con.MinDays ?? 0}"); } if ((con.MaxDays ?? 0) != 0) { lines.Add($"{nameof(SpawnConfiguration.ConditionWorldAgeDaysMax)}={con.MaxDays ?? 0}"); } } break; case ConditionNearbyPlayersCarryValue con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionNearbyPlayersCarryValue)}={con.RequiredValue}"); } break; case ConditionNearbyPlayersCarryItem con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionNearbyPlayerCarriesItem)}={con.ItemsSearchedFor.Join()}"); } break; case ConditionNearbyPlayersNoise con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionNearbyPlayersNoiseThreshold)}={con.NoiseThreshold.ToString(CultureInfo.InvariantCulture)}"); } break; case ConditionNearbyPlayersStatus con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionNearbyPlayersStatus)}={con.RequiredStatusEffects.Join()}"); } break; case ConditionGlobalKeysRequiredMissing con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.RequiredNotGlobalKey)}={con.RequiredMissing.Join()}"); } break; case ConditionLocation con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionLocation)}={con.Locations.Join()}"); } break; case ConditionAreaSpawnChance con: // Can't select entity ids in cfg files, so only output if it matches the template id to properly simulate what is possible. if (con.EntityId == template.Index) { if (con.AreaChance != 100) { if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionAreaSpawnChance)}={con.AreaChance.ToString(CultureInfo.InvariantCulture)}"); } } } break; case ConditionAreaIds con: if (AddedOptions.Add(con.GetType())) { lines.Add($"{nameof(SpawnConfiguration.ConditionAreaIds)}={con.RequiredAreaIds.Join()}"); } break; default: break; } } foreach (var modifier in template.SpawnModifiers) { switch (modifier) { case ModifierSetFaction mod: if (AddedOptions.Add(mod.GetType())) { lines.Add($"{nameof(SpawnConfiguration.SetFaction)}={mod.Faction?.ToString() ?? ""}"); } break; case ModifierSetRelentless mod: if (AddedOptions.Add(mod.GetType())) { if (mod.Relentless) { lines.Add($"{nameof(SpawnConfiguration.SetRelentless)}={mod.Relentless}"); } } break; case ModifierDespawnOnConditionsInvalid mod: if (AddedOptions.Add(mod.GetType())) { // Can't truly reflect the internal settings, so just treat it as set if the type is present. lines.Add($"{nameof(SpawnConfiguration.SetTryDespawnOnConditionsInvalid)}=true"); } break; case ModifierDespawnOnAlert mod: if (AddedOptions.Add(mod.GetType())) { if (mod.DespawnOnAlert) { lines.Add($"{nameof(SpawnConfiguration.SetTryDespawnOnAlert)}={mod.DespawnOnAlert}"); } } break; case ModifierSetTamed mod: if (AddedOptions.Add(mod.GetType())) { if (mod.Tamed) { lines.Add($"{nameof(SpawnConfiguration.SetTamed)}={mod.Tamed}"); } } break; case ModifierSetTamedCommandable mod: if (AddedOptions.Add(mod.GetType())) { if (mod.Commandable) { lines.Add($"{nameof(SpawnConfiguration.SetTamedCommandable)}={mod.Commandable}"); } } break; case ModifierSetTemplateId mod: if (AddedOptions.Add(mod.GetType())) { if (!string.IsNullOrWhiteSpace(mod.TemplateId)) { lines.Add($"{nameof(SpawnConfiguration.TemplateId)}={mod.TemplateId}"); } } break; default: break; } } if (Integrations.IntegrationManager.InstalledCLLC) { AddCllcIntegrationLines(lines, template); } if (Integrations.IntegrationManager.InstalledEpicLoot) { AddEpicLootLines(lines, template); } if (Integrations.IntegrationManager.InstalledMobAI) { AddMobAiLines(lines, template); } } lines.Add(""); return(lines); }