Decompiled source of ProgressiveSerpentSpawner v1.0.0

ProgressiveSerpentSpawner.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ProgressiveSerpentSpawner
{
	[BepInPlugin("ProgressiveSerpentSpawner", "ProgressiveSerpentSpawner", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "ProgressiveSerpentSpawner";

		public const string NAME = "ProgressiveSerpentSpawner";

		public const string VERSION = "1.0.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> TargetPrefabs;

		internal static ConfigEntry<string> BossKeys;

		internal static ConfigEntry<float> BonusPerBoss;

		internal static ConfigEntry<float> MaxChance;

		internal static ConfigEntry<float> BaseChanceOverride;

		internal static ConfigEntry<bool> VerboseLog;

		internal static readonly Dictionary<SpawnData, float> BaseChance = new Dictionary<SpawnData, float>();

		private static HashSet<string> _targets = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static List<string> _bossKeys = new List<string>();

		private static int _lastBossCount = -1;

		private static bool _dirty = true;

		private float _timer;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Geral", "Enabled", true, "Liga/desliga o ajuste de spawn.");
			TargetPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("1 - Geral", "TargetPrefabs", "Serpent", "Prefabs afetados (separados por vírgula).");
			BossKeys = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Progressão", "BossKeys", "defeated_eikthyr,defeated_gdking,defeated_bonemass,defeated_dragon,defeated_goblinking,defeated_queen,defeated_fader", "Global keys que contam como progressão (cada uma presente = +1 boss).");
			BonusPerBoss = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Progressão", "BonusPerBoss", 5f, new ConfigDescription("Bônus multiplicativo por boss derrotado. Chance final = base * (1 + BonusPerBoss * bosses). Ex: 5 com 1 boss = base x6. Máximo permitido: 5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			MaxChance = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Progressão", "MaxChance", 100f, new ConfigDescription("Teto da chance de spawn em % (0 a 100).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			BaseChanceOverride = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Progressão", "BaseChanceOverride", -1f, "Se >= 0, ignora a chance vanilla e usa esse valor (%) como base. -1 = usa vanilla.");
			VerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Debug", "VerboseLog", true, "Loga info do spawn da serpente e cada recálculo.");
			ParseConfig();
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				ParseConfig();
				_dirty = true;
			};
			_harmony = new Harmony("ProgressiveSerpentSpawner");
			_harmony.PatchAll();
			Log.LogInfo((object)"ProgressiveSerpentSpawner 1.0.0 carregado.");
		}

		private void OnDestroy()
		{
			RestoreAll();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void ParseConfig()
		{
			_targets = new HashSet<string>(from s in TargetPrefabs.Value.Split(',')
				select s.Trim() into s
				where s.Length > 0
				select s, StringComparer.OrdinalIgnoreCase);
			_bossKeys = (from s in BossKeys.Value.Split(',')
				select s.Trim().ToLowerInvariant() into s
				where s.Length > 0
				select s).Distinct().ToList();
		}

		private void Update()
		{
			_timer += Time.deltaTime;
			if (_timer < 5f)
			{
				return;
			}
			_timer = 0f;
			if (!((Object)(object)ZoneSystem.instance == (Object)null) && BaseChance.Count != 0)
			{
				int num = CountBosses();
				if (num != _lastBossCount || _dirty)
				{
					_lastBossCount = num;
					_dirty = false;
					ApplyAll(num);
				}
			}
		}

		internal static bool IsTarget(SpawnData sd)
		{
			if (sd == null || (Object)(object)sd.m_prefab == (Object)null)
			{
				return false;
			}
			return _targets.Contains(((Object)sd.m_prefab).name);
		}

		internal static void Register(SpawnData sd)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (!BaseChance.ContainsKey(sd))
			{
				BaseChance[sd] = sd.m_spawnChance;
				_dirty = true;
				if (VerboseLog.Value)
				{
					string arg = ((sd.m_requiredEnvironments != null && sd.m_requiredEnvironments.Count > 0) ? string.Join(",", sd.m_requiredEnvironments) : "qualquer");
					Log.LogInfo((object)($"[Registro] {((Object)sd.m_prefab).name} | nome='{sd.m_name}' | chance={sd.m_spawnChance}% | " + $"intervalo={sd.m_spawnInterval}s | max={sd.m_maxSpawned} | dia={sd.m_spawnAtDay} noite={sd.m_spawnAtNight} | " + $"clima={arg} | bioma={sd.m_biome} | enabled={sd.m_enabled}"));
				}
			}
		}

		internal static int CountBosses()
		{
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0;
			}
			int num = 0;
			foreach (string bossKey in _bossKeys)
			{
				if (instance.GetGlobalKey(bossKey))
				{
					num++;
				}
			}
			return num;
		}

		internal static float Compute(float baseChance, int bosses)
		{
			float num = ((BaseChanceOverride.Value >= 0f) ? BaseChanceOverride.Value : baseChance);
			float num2 = num * (1f + BonusPerBoss.Value * (float)bosses);
			float num3 = Mathf.Max(MaxChance.Value, num);
			return Mathf.Clamp(num2, num, num3);
		}

		internal static void ApplyAll(int bosses)
		{
			foreach (KeyValuePair<SpawnData, float> item in BaseChance)
			{
				SpawnData key = item.Key;
				float spawnChance = (Enabled.Value ? Compute(item.Value, bosses) : item.Value);
				key.m_spawnChance = spawnChance;
			}
			if (VerboseLog.Value)
			{
				KeyValuePair<SpawnData, float> keyValuePair = BaseChance.FirstOrDefault();
				if (keyValuePair.Key != null)
				{
					Log.LogInfo((object)($"[Recalc] bosses={bosses} | base={keyValuePair.Value}% -> atual={keyValuePair.Key.m_spawnChance:0.##}% " + $"({BaseChance.Count} entradas)"));
				}
			}
		}

		internal static void RestoreAll()
		{
			foreach (KeyValuePair<SpawnData, float> item in BaseChance)
			{
				if (item.Key != null)
				{
					item.Key.m_spawnChance = item.Value;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Awake")]
	internal static class SpawnSystem_Awake_Patch
	{
		private static void Postfix(SpawnSystem __instance)
		{
			if (__instance.m_spawnLists == null)
			{
				return;
			}
			foreach (SpawnSystemList spawnList in __instance.m_spawnLists)
			{
				if ((Object)(object)spawnList == (Object)null || spawnList.m_spawners == null)
				{
					continue;
				}
				foreach (SpawnData spawner in spawnList.m_spawners)
				{
					if (Plugin.IsTarget(spawner))
					{
						Plugin.Register(spawner);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	internal static class ZNet_Shutdown_Patch
	{
		private static void Prefix()
		{
			Plugin.RestoreAll();
			Plugin.BaseChance.Clear();
		}
	}
}