Beispiel #1
0
    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);
     }
 }
Beispiel #4
0
    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);
        }
    }
Beispiel #5
0
 private static void SetInstantiated(SpawnSystem __instance)
 {
     WorldSpawnerManager.EnsureInstantiatedSpawnListAssigned(__instance);
 }
Beispiel #6
0
 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);
    }