Decompiled source of StarLevelSystem v1.31.1

plugins/StarLevelSystem.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using MonoMod.Utils;
using SimpleJson;
using SoftReferenceableAssets;
using Splatform;
using StarLevelSystem.Data;
using StarLevelSystem.Modifiers;
using StarLevelSystem.Modifiers.Shared;
using StarLevelSystem.common;
using StarLevelSystem.modules;
using StarLevelSystem.modules.AnimationAndSpeed;
using StarLevelSystem.modules.CreatureSetup;
using StarLevelSystem.modules.Damage;
using StarLevelSystem.modules.Health;
using StarLevelSystem.modules.LevelSystem;
using StarLevelSystem.modules.LocationReset;
using StarLevelSystem.modules.Loot;
using StarLevelSystem.modules.Modifiers;
using StarLevelSystem.modules.NemesisSystem;
using StarLevelSystem.modules.Raids;
using StarLevelSystem.modules.Sizes;
using StarLevelSystem.modules.UI;
using TMPro;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("StarLevelSystem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("StarLevelSystem")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.31.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.31.1.0")]
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate0<T1, T2, T3>(T1 arg1 = default(T1), T2 arg2 = default(T2), T3 arg3 = default(T3));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate1<T1>(T1 arg = default(T1));
namespace StarLevelSystem
{
	[PublicAPI]
	public static class API
	{
		private static readonly Type APIReciever;

		private static readonly MethodInfo UpdateCreatureLevel;

		private static readonly MethodInfo UpdateCreatureColorization;

		private static readonly MethodInfo GetBaseAttributeValue;

		private static readonly MethodInfo UpdateCreatureBaseAttributes;

		private static readonly MethodInfo GetAllBaseAttributeValues;

		private static readonly MethodInfo SetAllBaseAttributeValues;

		private static readonly MethodInfo GetPerLevelAttributeValue;

		private static readonly MethodInfo UpdateCreaturePerLevelAttributes;

		private static readonly MethodInfo GetAllPerLevelAttributeValues;

		private static readonly MethodInfo SetAllPerLevelAttributeValues;

		private static readonly MethodInfo GetCreatureDamageRecievedModifier;

		private static readonly MethodInfo UpdateCreatureDamageRecievedModifier;

		private static readonly MethodInfo GetAllDamageRecievedModifiers;

		private static readonly MethodInfo SetAllDamageRecievedModifiers;

		private static readonly MethodInfo GetCreatureDamageBonus;

		private static readonly MethodInfo UpdateCreatureDamageBonus;

		private static readonly MethodInfo GetAllDamageBonus;

		private static readonly MethodInfo SetAllDamageBonus;

		private static readonly MethodInfo ApplyUpdatesToCreature;

		private static readonly MethodInfo SetCreatureSpawnManagedMethod;

		private static readonly MethodInfo GetPossibleModifiersForType;

		private static readonly MethodInfo GetAllModifiersForCreature;

		private static readonly MethodInfo AddModifierToCreature;

		private static readonly MethodInfo RemoveModifierFromCreatureMethod;

		private static readonly MethodInfo SetCreatureModifierConfigMethod;

		private static readonly MethodInfo ClearCreatureModifierConfigMethod;

		private static readonly MethodInfo GetCreatureModifierConfigMethod;

		private static readonly MethodInfo AddNewModifierToSLS;

		private static readonly MethodInfo SetEnemyHudChangesDisabledMethod;

		private static readonly MethodInfo GetDisabledEnemyHudChangesMethod;

		private static readonly MethodInfo GetCreatureHudInfoMethod;

		private static readonly MethodInfo GetCreatureEvolveProgressMethod;

		private static readonly MethodInfo RegisterLocationResetTargetMethod;

		private static readonly MethodInfo UnregisterLocationResetTargetMethod;

		private static readonly MethodInfo GetRegisteredLocationResetTargetsMethod;

		private static readonly MethodInfo GetLocationResetTargetInfoMethod;

		private static readonly MethodInfo IsLocationResetReadyMethod;

		private static readonly MethodInfo GetLocationResetStatusMethod;

		private static readonly MethodInfo IsKnownResetTargetNameMethod;

		private static readonly MethodInfo GetLocationLastResetMethod;

		private static readonly MethodInfo GetSecondsUntilLocationResetMethod;

		private static readonly MethodInfo GetLocationResetInfoMethod;

		private static readonly MethodInfo GetChunkResetInfoMethod;

		private static readonly MethodInfo ResetNamedLocationMethod;

		private static readonly MethodInfo ResetLocationsInRadiusMethod;

		public const int EnemyHudBarLayout = 1;

		public const int EnemyHudStars = 2;

		public const int EnemyHudEvolveBar = 4;

		public const int EnemyHudHealthNumbers = 8;

		public const int EnemyHudAll = 15;

		public static bool IsAvailable => APIReciever != null;

		public static bool SupportsLocationReset => ResetNamedLocationMethod != null;

		public static bool SupportsSpawnManaged => SetCreatureSpawnManagedMethod != null;

		public static bool SupportsModifierConfig => SetCreatureModifierConfigMethod != null;

		public static bool SupportsEnemyHud => SetEnemyHudChangesDisabledMethod != null;

		static API()
		{
			APIReciever = Type.GetType("StarLevelSystem.modules.APIReciever, StarLevelSystem");
			if (!(APIReciever == null))
			{
				UpdateCreatureLevel = APIReciever.GetMethod("UpdateCreatureLevel", BindingFlags.Static | BindingFlags.Public);
				UpdateCreatureColorization = APIReciever.GetMethod("UpdateCreatureColorization", BindingFlags.Static | BindingFlags.Public);
				GetBaseAttributeValue = APIReciever.GetMethod("GetBaseAttributeValue", BindingFlags.Static | BindingFlags.Public);
				UpdateCreatureBaseAttributes = APIReciever.GetMethod("UpdateCreatureBaseAttributes", BindingFlags.Static | BindingFlags.Public);
				GetAllBaseAttributeValues = APIReciever.GetMethod("GetAllBaseAttributes", BindingFlags.Static | BindingFlags.Public);
				SetAllBaseAttributeValues = APIReciever.GetMethod("SetAllBaseAttributes", BindingFlags.Static | BindingFlags.Public);
				GetPerLevelAttributeValue = APIReciever.GetMethod("GetPerLevelAttributeValue", BindingFlags.Static | BindingFlags.Public);
				UpdateCreaturePerLevelAttributes = APIReciever.GetMethod("UpdateCreaturePerLevelAttributes", BindingFlags.Static | BindingFlags.Public);
				GetAllPerLevelAttributeValues = APIReciever.GetMethod("GetAllPerLevelAttributes", BindingFlags.Static | BindingFlags.Public);
				SetAllPerLevelAttributeValues = APIReciever.GetMethod("SetAllPerLevelAttributes", BindingFlags.Static | BindingFlags.Public);
				GetCreatureDamageRecievedModifier = APIReciever.GetMethod("GetCreatureDamageRecievedModifier", BindingFlags.Static | BindingFlags.Public);
				UpdateCreatureDamageRecievedModifier = APIReciever.GetMethod("UpdateCreatureDamageRecievedModifier", BindingFlags.Static | BindingFlags.Public);
				GetAllDamageRecievedModifiers = APIReciever.GetMethod("GetAllDamageRecievedModifiers", BindingFlags.Static | BindingFlags.Public);
				SetAllDamageRecievedModifiers = APIReciever.GetMethod("SetAllDamageRecievedModifiers", BindingFlags.Static | BindingFlags.Public);
				GetCreatureDamageBonus = APIReciever.GetMethod("GetCreatureDamageBonus", BindingFlags.Static | BindingFlags.Public);
				UpdateCreatureDamageBonus = APIReciever.GetMethod("UpdateCreatureDamageBonus", BindingFlags.Static | BindingFlags.Public);
				GetAllDamageBonus = APIReciever.GetMethod("GetAllDamageBonus", BindingFlags.Static | BindingFlags.Public);
				SetAllDamageBonus = APIReciever.GetMethod("SetAllDamageBonus", BindingFlags.Static | BindingFlags.Public);
				ApplyUpdatesToCreature = APIReciever.GetMethod("ApplyUpdatesToCreature", BindingFlags.Static | BindingFlags.Public);
				SetCreatureSpawnManagedMethod = APIReciever.GetMethod("SetCreatureSpawnManaged", BindingFlags.Static | BindingFlags.Public);
				GetPossibleModifiersForType = APIReciever.GetMethod("GetPossibleModifiersForType", BindingFlags.Static | BindingFlags.Public);
				GetAllModifiersForCreature = APIReciever.GetMethod("GetAllModifiersForCreature", BindingFlags.Static | BindingFlags.Public);
				AddModifierToCreature = APIReciever.GetMethod("AddModifierToCreature", BindingFlags.Static | BindingFlags.Public);
				RemoveModifierFromCreatureMethod = APIReciever.GetMethod("RemoveModifierFromCreature", BindingFlags.Static | BindingFlags.Public);
				SetCreatureModifierConfigMethod = APIReciever.GetMethod("SetCreatureModifierConfig", BindingFlags.Static | BindingFlags.Public);
				ClearCreatureModifierConfigMethod = APIReciever.GetMethod("ClearCreatureModifierConfig", BindingFlags.Static | BindingFlags.Public);
				GetCreatureModifierConfigMethod = APIReciever.GetMethod("GetCreatureModifierConfig", BindingFlags.Static | BindingFlags.Public);
				AddNewModifierToSLS = APIReciever.GetMethod("AddNewModifierToSLS", BindingFlags.Static | BindingFlags.Public);
				SetEnemyHudChangesDisabledMethod = APIReciever.GetMethod("SetEnemyHudChangesDisabled", BindingFlags.Static | BindingFlags.Public);
				GetDisabledEnemyHudChangesMethod = APIReciever.GetMethod("GetDisabledEnemyHudChanges", BindingFlags.Static | BindingFlags.Public);
				GetCreatureHudInfoMethod = APIReciever.GetMethod("GetCreatureHudInfo", BindingFlags.Static | BindingFlags.Public);
				GetCreatureEvolveProgressMethod = APIReciever.GetMethod("GetCreatureEvolveProgress", BindingFlags.Static | BindingFlags.Public);
				RegisterLocationResetTargetMethod = APIReciever.GetMethod("RegisterLocationResetTarget", BindingFlags.Static | BindingFlags.Public);
				UnregisterLocationResetTargetMethod = APIReciever.GetMethod("UnregisterLocationResetTarget", BindingFlags.Static | BindingFlags.Public);
				GetRegisteredLocationResetTargetsMethod = APIReciever.GetMethod("GetRegisteredLocationResetTargets", BindingFlags.Static | BindingFlags.Public);
				GetLocationResetTargetInfoMethod = APIReciever.GetMethod("GetLocationResetTargetInfo", BindingFlags.Static | BindingFlags.Public);
				IsLocationResetReadyMethod = APIReciever.GetMethod("IsLocationResetReady", BindingFlags.Static | BindingFlags.Public);
				GetLocationResetStatusMethod = APIReciever.GetMethod("GetLocationResetStatus", BindingFlags.Static | BindingFlags.Public);
				IsKnownResetTargetNameMethod = APIReciever.GetMethod("IsKnownResetTargetName", BindingFlags.Static | BindingFlags.Public);
				GetLocationLastResetMethod = APIReciever.GetMethod("GetLocationLastReset", BindingFlags.Static | BindingFlags.Public);
				GetSecondsUntilLocationResetMethod = APIReciever.GetMethod("GetSecondsUntilLocationReset", BindingFlags.Static | BindingFlags.Public);
				GetLocationResetInfoMethod = APIReciever.GetMethod("GetLocationResetInfo", BindingFlags.Static | BindingFlags.Public);
				GetChunkResetInfoMethod = APIReciever.GetMethod("GetChunkResetInfo", BindingFlags.Static | BindingFlags.Public);
				ResetNamedLocationMethod = APIReciever.GetMethod("ResetNamedLocation", BindingFlags.Static | BindingFlags.Public);
				ResetLocationsInRadiusMethod = APIReciever.GetMethod("ResetLocationsInRadius", BindingFlags.Static | BindingFlags.Public);
			}
		}

		private static object Call(MethodInfo method, object fallback, params object[] args)
		{
			if (method == null)
			{
				return fallback;
			}
			return method.Invoke(null, args);
		}

		public static bool SetCreatureLevel(Character creatureId, int newLevel)
		{
			return (bool)UpdateCreatureLevel.Invoke(null, new object[2] { creatureId, newLevel });
		}

		public static bool SetCreatureColorization(Character creatureId, float value, float hue, float sat, bool emission = false)
		{
			return (bool)UpdateCreatureColorization.Invoke(null, new object[5] { creatureId, value, hue, sat, emission });
		}

		public static float GetCreatureBaseAttribute(Character creatureId, int attribute)
		{
			return (float)GetBaseAttributeValue.Invoke(null, new object[2] { creatureId, attribute });
		}

		public static bool SetCreatureBaseAttribute(Character creatureId, int attribute, float value)
		{
			return (bool)UpdateCreatureBaseAttributes.Invoke(null, new object[3] { creatureId, attribute, value });
		}

		public static Dictionary<int, float> GetAllCreatureBaseAttributes(Character creatureId)
		{
			return (Dictionary<int, float>)GetAllBaseAttributeValues.Invoke(null, new object[1] { creatureId });
		}

		public static bool SetAllCreatureBaseAttributes(Character creatureId, Dictionary<int, float> attributes)
		{
			return (bool)SetAllBaseAttributeValues.Invoke(null, new object[2] { creatureId, attributes });
		}

		public static float GetCreaturePerLevelAttribute(Character creatureId, int attribute)
		{
			return (float)GetPerLevelAttributeValue.Invoke(null, new object[2] { creatureId, attribute });
		}

		public static bool SetCreaturePerLevelAttribute(Character creatureId, int attribute, float value)
		{
			return (bool)UpdateCreaturePerLevelAttributes.Invoke(null, new object[3] { creatureId, attribute, value });
		}

		public static Dictionary<int, float> GetAllCreaturePerLevelAttributes(Character creatureId)
		{
			return (Dictionary<int, float>)GetAllPerLevelAttributeValues.Invoke(null, new object[1] { creatureId });
		}

		public static bool SetAllCreaturePerLevelAttributes(Character creatureId, Dictionary<int, float> attributes)
		{
			return (bool)SetAllPerLevelAttributeValues.Invoke(null, new object[2] { creatureId, attributes });
		}

		public static float GetCreatureDamageReceivedModifier(Character creatureId, int damageType)
		{
			return (float)GetCreatureDamageRecievedModifier.Invoke(null, new object[2] { creatureId, damageType });
		}

		public static bool SetCreatureDamageReceivedModifier(Character creatureId, int damageType, float value)
		{
			return (bool)UpdateCreatureDamageRecievedModifier.Invoke(null, new object[3] { creatureId, damageType, value });
		}

		public static Dictionary<int, float> GetAllCreatureDamageReceivedModifiers(Character creatureId)
		{
			return (Dictionary<int, float>)GetAllDamageRecievedModifiers.Invoke(null, new object[1] { creatureId });
		}

		public static bool SetAllCreatureDamageReceivedModifiers(Character creatureId, Dictionary<int, float> attributes)
		{
			return (bool)SetAllDamageRecievedModifiers.Invoke(null, new object[2] { creatureId, attributes });
		}

		public static float GetCreatureFlatDamageBonus(Character creatureId, int damageType)
		{
			return (float)GetCreatureDamageBonus.Invoke(null, new object[2] { creatureId, damageType });
		}

		public static bool SetCreatureFlatDamageBonus(Character creatureId, int damageType, float value)
		{
			return (bool)UpdateCreatureDamageBonus.Invoke(null, new object[3] { creatureId, damageType, value });
		}

		public static Dictionary<int, float> GetAllCreatureFlatDamageBonuses(Character creatureId)
		{
			return (Dictionary<int, float>)GetAllDamageBonus.Invoke(null, new object[1] { creatureId });
		}

		public static bool SetAllCreatureFlatDamageBonuses(Character creatureId, Dictionary<int, float> attributes)
		{
			return (bool)SetAllDamageBonus.Invoke(null, new object[2] { creatureId, attributes });
		}

		public static bool ApplyCreatureUpdates(Character creatureId)
		{
			return (bool)ApplyUpdatesToCreature.Invoke(null, new object[1] { creatureId });
		}

		public static bool SetCreatureSpawnManaged(Character creatureId, bool managed = true)
		{
			return (bool)Call(SetCreatureSpawnManagedMethod, false, creatureId, managed);
		}

		public static List<string> GetPossibleModifiers(int modType = 0)
		{
			return (List<string>)GetPossibleModifiersForType.Invoke(null, new object[1] { modType });
		}

		public static Dictionary<string, int> GetCreaturesModifiers(Character creatureId)
		{
			return (Dictionary<string, int>)GetAllModifiersForCreature.Invoke(null, new object[1] { creatureId });
		}

		public static bool AddModifierToTargetCreature(Character creatureId, string modifierName, int modifierType, bool update = true)
		{
			return (bool)AddModifierToCreature.Invoke(null, new object[4] { creatureId, modifierName, modifierType, update });
		}

		public static bool RemoveModifierFromTargetCreature(Character creatureId, string modifierName)
		{
			return (bool)Call(RemoveModifierFromCreatureMethod, false, creatureId, modifierName);
		}

		public static bool SetCreatureModifierConfig(Character creatureId, string modifierName, Dictionary<string, float> values)
		{
			return (bool)Call(SetCreatureModifierConfigMethod, false, creatureId, modifierName, values);
		}

		public static bool ClearCreatureModifierConfig(Character creatureId, string modifierName, string key = null)
		{
			return (bool)Call(ClearCreatureModifierConfigMethod, false, creatureId, modifierName, key);
		}

		public static Dictionary<string, float> GetCreatureModifierConfig(Character creatureId, string modifierName, int modifierType = -1)
		{
			return (Dictionary<string, float>)Call(GetCreatureModifierConfigMethod, null, creatureId, modifierName, modifierType);
		}

		public static bool SetEnemyHudChangesDisabled(string sourceId, int changes)
		{
			return (bool)Call(SetEnemyHudChangesDisabledMethod, false, sourceId, changes);
		}

		public static int GetDisabledEnemyHudChanges()
		{
			return (int)Call(GetDisabledEnemyHudChangesMethod, 0);
		}

		public static Dictionary<string, object> GetCreatureHudInfo(Character creatureId)
		{
			return (Dictionary<string, object>)Call(GetCreatureHudInfoMethod, null, creatureId);
		}

		public static float GetCreatureEvolveProgress(Character creatureId)
		{
			return (float)Call(GetCreatureEvolveProgressMethod, -1f, creatureId);
		}

		public static bool AddNewModifier(int modifierID, string modifier_name, Delegate setupMethod = null, float selectionWeight = 10f, float basepower = 0f, float perlevelpower = 0f, Dictionary<Biome, List<string>> biomeConfig = null, int namingStyle = 2, string name_suffixes = null, string name_prefixes = null, int visualStyle = 0, Sprite starIcon = null, GameObject visualEffect = null, List<string> allowed_creatures = null, List<string> unallowed_creatures = null, List<Biome> allowed_biomes = null)
		{
			return (bool)AddNewModifierToSLS.Invoke(null, new object[16]
			{
				modifierID, modifier_name, setupMethod, selectionWeight, basepower, perlevelpower, biomeConfig, namingStyle, name_suffixes, name_prefixes,
				visualStyle, starIcon, visualEffect, allowed_creatures, unallowed_creatures, allowed_biomes
			});
		}

		public static bool RegisterLocationReset(string prefabName, string sourceId, float resetHours = 0f, string resetSchedule = null, bool enabled = true, int mode = 0, bool resetTerrain = false, float terrainRadius = 0f, float extraTerrainRadius = 0f, bool resetInterior = true, float minDistance = 0f, float maxDistance = 0f, Action<bool> onResult = null)
		{
			return (bool)Call(RegisterLocationResetTargetMethod, false, prefabName, sourceId, resetHours, resetSchedule, mode, resetTerrain, terrainRadius, extraTerrainRadius, resetInterior, minDistance, maxDistance, enabled, onResult);
		}

		public static bool UnregisterLocationReset(string prefabName, string sourceId, Action<bool> onResult = null)
		{
			return (bool)Call(UnregisterLocationResetTargetMethod, false, prefabName, sourceId, onResult);
		}

		public static bool GetRegisteredLocationResets(string sourceId, Action<List<string>> onResult)
		{
			return (bool)Call(GetRegisteredLocationResetTargetsMethod, false, sourceId, onResult);
		}

		public static bool GetLocationResetTargetInfo(string prefabName, Action<Dictionary<string, object>> onResult)
		{
			return (bool)Call(GetLocationResetTargetInfoMethod, false, prefabName, onResult);
		}

		public static bool IsLocationResetReady(Action<bool> onResult)
		{
			return (bool)Call(IsLocationResetReadyMethod, false, onResult);
		}

		public static bool GetLocationResetStatus(Action<Dictionary<string, object>> onResult)
		{
			return (bool)Call(GetLocationResetStatusMethod, false, onResult);
		}

		public static bool IsKnownLocationResetTarget(string prefabName, Action<bool> onResult)
		{
			return (bool)Call(IsKnownResetTargetNameMethod, false, prefabName, onResult);
		}

		public static bool GetLocationLastReset(string locationName, Vector3 center, float radius, Action<long> onResult)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(GetLocationLastResetMethod, false, locationName, center, radius, onResult);
		}

		public static bool GetSecondsUntilLocationReset(string locationName, Vector3 center, float radius, Action<double> onResult)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(GetSecondsUntilLocationResetMethod, false, locationName, center, radius, onResult);
		}

		public static bool GetLocationResetInfo(string locationName, Vector3 center, float radius, Action<Dictionary<string, object>> onResult)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(GetLocationResetInfoMethod, false, locationName, center, radius, onResult);
		}

		public static bool GetChunkResetInfo(Vector3 position, bool includePrefabs, Action<Dictionary<string, object>> onResult)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(GetChunkResetInfoMethod, false, position, includePrefabs, onResult);
		}

		public static bool ResetNamedLocation(string locationName, Vector3 center, float radius = 128f, int safety = 0, bool resetAllMatches = false, float safeWaitSeconds = 0f, bool includeDetail = false, Action<Dictionary<string, object>> onComplete = null)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(ResetNamedLocationMethod, false, locationName, center, radius, safety, resetAllMatches, safeWaitSeconds, includeDetail, onComplete);
		}

		public static bool ResetLocationsInRadius(Vector3 center, float radius = 128f, int safety = 0, float safeWaitSeconds = 0f, bool includeDetail = false, Action<Dictionary<string, object>> onComplete = null)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return (bool)Call(ResetLocationsInRadiusMethod, false, center, radius, safety, safeWaitSeconds, includeDetail, onComplete);
		}
	}
	internal static class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static bool IsDebugEnabled => (int)Level >= 32;

		public static void EnableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogNemesis(string message)
		{
			if (ValConfig.EnableDebugNemesisDetails.Value)
			{
				StarLevelSystem.Log.LogInfo((object)("[Nemesis] " + message));
			}
		}

		public static void LogRaid(string message)
		{
			if (ValConfig.EnableDebugRaidDetails.Value)
			{
				StarLevelSystem.Log.LogInfo((object)("[Raid] " + message));
			}
		}

		public static void LogLoot(string message)
		{
			if (ValConfig.EnableDebugLootDetails.Value)
			{
				StarLevelSystem.Log.LogInfo((object)("[Loot] " + message));
			}
		}

		public static void LogLocationReset(string message)
		{
			if (ValConfig.EnableDebugLocationResetDetails.Value)
			{
				StarLevelSystem.Log.LogInfo((object)("[LocationReset] " + message));
			}
		}

		public static void LogLocationResetAlways(string message)
		{
			StarLevelSystem.Log.LogInfo((object)("[LocationReset] " + message));
		}

		public static void LogLocationResetWarning(string message)
		{
			StarLevelSystem.Log.LogWarning((object)("[LocationReset] " + message));
		}

		public static void LogLocationResetError(string message)
		{
			StarLevelSystem.Log.LogError((object)("[LocationReset] " + message));
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				StarLevelSystem.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				StarLevelSystem.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				StarLevelSystem.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				StarLevelSystem.Log.LogError((object)message);
			}
		}
	}
	[BepInPlugin("MidnightsFX.StarLevelSystem", "StarLevelSystem", "1.31.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("org.bepinex.plugins.creaturelevelcontrol")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class StarLevelSystem : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.StarLevelSystem";

		public const string PluginName = "StarLevelSystem";

		public const string PluginVersion = "1.31.1";

		public ValConfig cfg;

		public static CustomLocalization Localization;

		public static AssetBundle EmbeddedResourceBundle;

		public static ManualLogSource Log;

		public static Harmony HarmonyInstance { get; private set; }

		public void Awake()
		{
			Localization = LocalizationManager.Instance.GetLocalization();
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			cfg.SetupConfigRPCs();
			TaskRunner.Setup();
			Compatibility.CheckModCompat();
			EmbeddedResourceBundle = LoadEmbeddedBundle("StarLevelSystem.assets.starlevelsystems");
			HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "MidnightsFX.StarLevelSystem");
			Compatibility.ApplyConditionalPatches(HarmonyInstance);
			Colorization.UpdateMapColorSelection();
			Colorization.UpdateZoneOverlayColorSelection();
			YamlConfigManager.Init();
			QuickConfigureTool.Init();
			LocalizationLoader.AddLocalizations();
			PrefabManager.OnVanillaPrefabsAvailable += CreatureModifiersData.LoadPrefabs;
			PrefabManager.OnVanillaPrefabsAvailable += UpdateLevelsOnChange.UpdateFishMaxLevel;
			PrefabManager.OnVanillaPrefabsAvailable += UpdateLevelsOnChange.UpdateFishScaleByQuality;
			PrefabManager.OnVanillaPrefabsAvailable += UIHudControl.SetDefaultStar;
			PrefabManager.OnVanillaPrefabsAvailable += NemesisRemoteSpawnControl.LoadAssets;
			PrefabManager.OnPrefabsRegistered += PrefabLookup.ResetWarnings;
			PrefabManager.OnPrefabsRegistered += SwimAnimationModifications.ApplyToPrefabs;
			PrefabManager.OnPrefabsRegistered += LootSystemData.AttachPrefabsWhenReady;
			MinimapManager.OnVanillaMapDataLoaded += DistanceScaleSystem.DelayedMinimapSetup;
			MinimapManager.OnVanillaMapDataLoaded += ZoneScaleSystem.Initialize;
			MinimapManager.OnVanillaMapDataLoaded += NemesisMinimap.OnMapReady;
			PrefabManager.OnPrefabsRegistered += SizeModifications.PrepareSizeRefCache;
			PrefabManager.OnPrefabsRegistered += NovaBurstFx.Register;
			PrefabManager.OnPrefabsRegistered += ModifierSounds.Apply;
			UIHudControl.LoadAssets();
			ModifierStatusEffects.Register();
			RaidControl.LoadAssets();
			TerminalManager.Init();
			NemesisSystem.Initialize();
		}

		private static AssetBundle LoadEmbeddedBundle(string resourceName)
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Assembly assembly = typeof(StarLevelSystem).Assembly;
			string text = assembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(resourceName));
			if (text == null)
			{
				Log.LogError((object)("The asset bundle " + resourceName + " is not embedded in this build."));
				return null;
			}
			byte[] array;
			using (Stream stream = assembly.GetManifestResourceStream(text))
			{
				array = new byte[stream.Length];
				int num2;
				for (int num = 0; num < array.Length; num += num2)
				{
					num2 = stream.Read(array, num, array.Length - num);
					if (num2 <= 0)
					{
						break;
					}
				}
			}
			AssetBundle result = AssetBundle.LoadFromMemory(array);
			Logger.LogDebug($"Opened the embedded asset bundle ({array.Length / 1024} KB) from memory in {stopwatch.Elapsed.TotalMilliseconds:0.0} ms.");
			return result;
		}
	}
}
namespace StarLevelSystem.modules
{
	internal static class APIOwnerRelay
	{
		internal enum Op
		{
			SetLevel,
			SetSpawnManaged,
			UpdateBaseAttribute,
			SetAllBaseAttributes,
			UpdatePerLevelAttribute,
			SetAllPerLevelAttributes,
			UpdateDamageRecieved,
			SetAllDamageRecieved,
			UpdateDamageBonus,
			SetAllDamageBonus,
			ApplyUpdates,
			AddModifier,
			RemoveModifier,
			SetModifierConfig,
			ClearModifierConfig
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		public static class RegisterApiRelayRPC
		{
			private static void Postfix(Character __instance)
			{
				if (!__instance.IsPlayer() && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.GetZDO() != null)
				{
					__instance.m_nview.Register<ZPackage>("SLS_ApiRelay", (Action<long, ZPackage>)delegate(long sender, ZPackage call)
					{
						Replay(__instance, call);
					});
				}
			}
		}

		private const string RPC_ApiRelay = "SLS_ApiRelay";

		private const int MaxHops = 3;

		internal static void ClaimIfUnowned(Character chara)
		{
			ZNetView val = (((Object)(object)chara != (Object)null) ? chara.m_nview : null);
			if (!((Object)(object)val == (Object)null) && val.IsValid() && !val.GetZDO().HasOwner())
			{
				val.ClaimOwnership();
			}
		}

		internal static void SendToOwner(Character chara, Op op, Action<ZPackage> writeArgs = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ZNetView val = (((Object)(object)chara != (Object)null) ? chara.m_nview : null);
			if (!((Object)(object)val == (Object)null) && val.IsValid() && !val.IsOwner())
			{
				ZPackage val2 = new ZPackage();
				writeArgs?.Invoke(val2);
				Send(val, 0, op, val2);
			}
		}

		internal static void WriteAttributes(ZPackage package, Dictionary<int, float> attributes)
		{
			package.Write(attributes.Count);
			foreach (KeyValuePair<int, float> attribute in attributes)
			{
				package.Write(attribute.Key);
				package.Write(attribute.Value);
			}
		}

		internal static void WriteValues(ZPackage package, Dictionary<string, float> values)
		{
			package.Write(values.Count);
			foreach (KeyValuePair<string, float> value in values)
			{
				package.Write(value.Key);
				package.Write(value.Value);
			}
		}

		private static Dictionary<string, float> ReadValues(ZPackage package)
		{
			int num = package.ReadInt();
			Dictionary<string, float> dictionary = new Dictionary<string, float>(num);
			for (int i = 0; i < num; i++)
			{
				string key = package.ReadString();
				dictionary[key] = package.ReadSingle();
			}
			return dictionary;
		}

		private static Dictionary<int, float> ReadAttributes(ZPackage package)
		{
			int num = package.ReadInt();
			Dictionary<int, float> dictionary = new Dictionary<int, float>(num);
			for (int i = 0; i < num; i++)
			{
				int key = package.ReadInt();
				dictionary[key] = package.ReadSingle();
			}
			return dictionary;
		}

		private static void Send(ZNetView nview, int hops, Op op, ZPackage args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(hops);
			val.Write((int)op);
			val.Write(args);
			nview.InvokeRPC("SLS_ApiRelay", new object[1] { val });
		}

		private static void Replay(Character chara, ZPackage call)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || !chara.m_nview.IsValid())
			{
				return;
			}
			int num = call.ReadInt();
			Op op = (Op)call.ReadInt();
			ZPackage val = call.ReadPackage();
			ZNetView nview = chara.m_nview;
			if (!nview.IsOwner() && nview.GetZDO().HasOwner())
			{
				if (num < 3)
				{
					Send(nview, num + 1, op, val);
				}
				else
				{
					Logger.LogWarning($"SLS-API: dropping a replayed {op} for {((Object)chara).name}: its owner kept changing while the call was in flight.");
				}
				return;
			}
			switch (op)
			{
			case Op.SetLevel:
			{
				int num3 = val.ReadInt();
				if (num3 < 1)
				{
					Logger.LogWarning($"SLS-API: dropping a replayed {op} for {((Object)chara).name}: {num3} is not a creature level.");
				}
				else
				{
					APIReciever.UpdateCreatureLevel(chara, num3);
				}
				break;
			}
			case Op.SetSpawnManaged:
				APIReciever.SetCreatureSpawnManaged(chara, val.ReadBool());
				break;
			case Op.UpdateBaseAttribute:
			{
				int attribute = val.ReadInt();
				APIReciever.UpdateCreatureBaseAttributes(chara, attribute, val.ReadSingle());
				break;
			}
			case Op.SetAllBaseAttributes:
				APIReciever.SetAllBaseAttributes(chara, ReadAttributes(val));
				break;
			case Op.UpdatePerLevelAttribute:
			{
				int attribute2 = val.ReadInt();
				APIReciever.UpdateCreaturePerLevelAttributes(chara, attribute2, val.ReadSingle());
				break;
			}
			case Op.SetAllPerLevelAttributes:
				APIReciever.SetAllPerLevelAttributes(chara, ReadAttributes(val));
				break;
			case Op.UpdateDamageRecieved:
			{
				int attribute4 = val.ReadInt();
				APIReciever.UpdateCreatureDamageRecievedModifier(chara, attribute4, val.ReadSingle());
				break;
			}
			case Op.SetAllDamageRecieved:
				APIReciever.SetAllDamageRecievedModifiers(chara, ReadAttributes(val));
				break;
			case Op.UpdateDamageBonus:
			{
				int attribute3 = val.ReadInt();
				APIReciever.UpdateCreatureDamageBonus(chara, attribute3, val.ReadSingle());
				break;
			}
			case Op.SetAllDamageBonus:
				APIReciever.SetAllDamageBonus(chara, ReadAttributes(val));
				break;
			case Op.ApplyUpdates:
				APIReciever.ApplyUpdatesToCreature(chara);
				break;
			case Op.AddModifier:
			{
				string modifierName3 = val.ReadString();
				int num2 = val.ReadInt();
				bool update = val.ReadBool();
				if (!Enum.IsDefined(typeof(DataObjects.ModifierType), num2))
				{
					Logger.LogWarning($"SLS-API: dropping a replayed {op} for {((Object)chara).name}: {num2} is not a modifier type.");
				}
				else
				{
					APIReciever.AddModifierToCreature(chara, modifierName3, num2, update);
				}
				break;
			}
			case Op.RemoveModifier:
				APIReciever.RemoveModifierFromCreature(chara, val.ReadString());
				break;
			case Op.SetModifierConfig:
			{
				string modifierName2 = val.ReadString();
				APIReciever.SetCreatureModifierConfig(chara, modifierName2, ReadValues(val));
				break;
			}
			case Op.ClearModifierConfig:
			{
				string modifierName = val.ReadString();
				bool flag = val.ReadBool();
				string text = val.ReadString();
				APIReciever.ClearCreatureModifierConfig(chara, modifierName, flag ? text : null);
				break;
			}
			default:
				Logger.LogWarning($"SLS-API: unknown replayed call {(int)op} for {((Object)chara).name}.");
				break;
			}
		}
	}
	public static class APIReciever
	{
		public static bool UpdateCreatureLevel(Character chara, int level)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			Logger.LogDebug($"SLS-API: Update Creature level {chara} - {level}");
			APIOwnerRelay.ClaimIfUnowned(chara);
			LevelSelection.SetAndUpdateCharacterLevel(chara, level);
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetLevel, delegate(ZPackage args)
			{
				args.Write(level);
			});
			return true;
		}

		public static bool UpdateCreatureColorization(Character chara, float value, float hue, float sat, bool emission = false)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			DataObjects.CharacterCacheEntry cacheEntry = CompositeLazyCache.GetCacheEntry(chara);
			if (cacheEntry == null)
			{
				return false;
			}
			cacheEntry.Colorization = new DataObjects.ColorDef(hue, sat, value, emission);
			CompositeLazyCache.UpdateCharacterCacheEntry(chara, cacheEntry);
			Colorization.ApplyColorizationWithoutLevelEffects(((Component)chara).gameObject, cacheEntry.Colorization);
			return true;
		}

		public static bool SetCreatureSpawnManaged(Character chara, bool managed)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (CompositeLazyCache.IsZOwner(chara))
			{
				ZDO zDO = chara.m_nview.GetZDO();
				zDO.Set(DataObjects.SLS_SPAWN_MANAGED, managed);
				if (managed)
				{
					zDO.Set(DataObjects.SLS_SPAWN_MULT, true);
				}
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetSpawnManaged, delegate(ZPackage args)
			{
				args.Write(managed);
			});
			return true;
		}

		public static float GetBaseAttributeValue(Character chara, int attribute)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return -1f;
			}
			return CompositeLazyCache.GetAndSetLocalCache(chara)?.CreatureBaseValueModifiers[(DataObjects.CreatureBaseAttribute)attribute] ?? (-1f);
		}

		public static bool UpdateCreatureBaseAttributes(Character chara, int attribute, float value)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.Base, StatValues(attribute, value)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.UpdateBaseAttribute, delegate(ZPackage args)
			{
				args.Write(attribute);
				args.Write(value);
			});
			return true;
		}

		public static Dictionary<int, float> GetAllBaseAttributes(Character chara)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return null;
			}
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return null;
			}
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			foreach (KeyValuePair<DataObjects.CreatureBaseAttribute, float> creatureBaseValueModifier in andSetLocalCache.CreatureBaseValueModifiers)
			{
				dictionary[(int)creatureBaseValueModifier.Key] = creatureBaseValueModifier.Value;
			}
			return dictionary;
		}

		public static bool SetAllBaseAttributes(Character chara, Dictionary<int, float> attributes)
		{
			if ((Object)(object)chara == (Object)null || attributes == null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.Base, StatValues(attributes)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetAllBaseAttributes, delegate(ZPackage args)
			{
				APIOwnerRelay.WriteAttributes(args, attributes);
			});
			return true;
		}

		public static float GetPerLevelAttributeValue(Character chara, int attribute)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return -1f;
			}
			return CompositeLazyCache.GetAndSetLocalCache(chara)?.CreaturePerLevelValueModifiers[(DataObjects.CreaturePerLevelAttribute)attribute] ?? (-1f);
		}

		public static bool UpdateCreaturePerLevelAttributes(Character chara, int attribute, float value)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.PerLevel, StatValues(attribute, value)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.UpdatePerLevelAttribute, delegate(ZPackage args)
			{
				args.Write(attribute);
				args.Write(value);
			});
			return true;
		}

		public static Dictionary<int, float> GetAllPerLevelAttributes(Character chara)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return null;
			}
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return null;
			}
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			foreach (KeyValuePair<DataObjects.CreaturePerLevelAttribute, float> creaturePerLevelValueModifier in andSetLocalCache.CreaturePerLevelValueModifiers)
			{
				dictionary[(int)creaturePerLevelValueModifier.Key] = creaturePerLevelValueModifier.Value;
			}
			return dictionary;
		}

		public static bool SetAllPerLevelAttributes(Character chara, Dictionary<int, float> attributes)
		{
			if ((Object)(object)chara == (Object)null || attributes == null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.PerLevel, StatValues(attributes)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetAllPerLevelAttributes, delegate(ZPackage args)
			{
				APIOwnerRelay.WriteAttributes(args, attributes);
			});
			return true;
		}

		public static float GetCreatureDamageRecievedModifier(Character chara, int attribute)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return -1f;
			}
			return CompositeLazyCache.GetAndSetLocalCache(chara)?.DamageRecievedModifiers[(DataObjects.DamageType)attribute] ?? (-1f);
		}

		public static bool UpdateCreatureDamageRecievedModifier(Character chara, int attribute, float value)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.DamageTaken, StatValues(attribute, value)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.UpdateDamageRecieved, delegate(ZPackage args)
			{
				args.Write(attribute);
				args.Write(value);
			});
			return true;
		}

		public static Dictionary<int, float> GetAllDamageRecievedModifiers(Character chara)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return null;
			}
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return null;
			}
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			foreach (KeyValuePair<DataObjects.DamageType, float> damageRecievedModifier in andSetLocalCache.DamageRecievedModifiers)
			{
				dictionary[(int)damageRecievedModifier.Key] = damageRecievedModifier.Value;
			}
			return dictionary;
		}

		public static bool SetAllDamageRecievedModifiers(Character chara, Dictionary<int, float> attributes)
		{
			if ((Object)(object)chara == (Object)null || attributes == null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.DamageTaken, StatValues(attributes)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetAllDamageRecieved, delegate(ZPackage args)
			{
				APIOwnerRelay.WriteAttributes(args, attributes);
			});
			return true;
		}

		public static float GetCreatureDamageBonus(Character chara, int attribute)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return -1f;
			}
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return -1f;
			}
			if (andSetLocalCache.CreatureDamageBonus.ContainsKey((DataObjects.DamageType)attribute))
			{
				return andSetLocalCache.CreatureDamageBonus[(DataObjects.DamageType)attribute];
			}
			return 0f;
		}

		public static bool UpdateCreatureDamageBonus(Character chara, int attribute, float value)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.DamageBonus, StatValues(attribute, value)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.UpdateDamageBonus, delegate(ZPackage args)
			{
				args.Write(attribute);
				args.Write(value);
			});
			return true;
		}

		public static Dictionary<int, float> GetAllDamageBonus(Character chara)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return null;
			}
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return null;
			}
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			foreach (KeyValuePair<DataObjects.DamageType, float> creatureDamageBonu in andSetLocalCache.CreatureDamageBonus)
			{
				dictionary[(int)creatureDamageBonu.Key] = creatureDamageBonu.Value;
			}
			return dictionary;
		}

		public static bool SetAllDamageBonus(Character chara, Dictionary<int, float> attributes)
		{
			if ((Object)(object)chara == (Object)null || attributes == null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CreatureStatOverrides.Apply(chara, StatGroup.DamageBonus, StatValues(attributes)))
			{
				return false;
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetAllDamageBonus, delegate(ZPackage args)
			{
				APIOwnerRelay.WriteAttributes(args, attributes);
			});
			return true;
		}

		private static Dictionary<int, float?> StatValues(int attribute, float value)
		{
			return new Dictionary<int, float?> { { attribute, value } };
		}

		private static Dictionary<int, float?> StatValues(Dictionary<int, float> attributes)
		{
			Dictionary<int, float?> dictionary = new Dictionary<int, float?>(attributes.Count);
			foreach (KeyValuePair<int, float> attribute in attributes)
			{
				dictionary[attribute.Key] = attribute.Value;
			}
			return dictionary;
		}

		public static bool ApplyUpdatesToCreature(Character chara)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			DataObjects.CharacterCacheEntry andSetLocalCache = CompositeLazyCache.GetAndSetLocalCache(chara);
			if (andSetLocalCache == null)
			{
				return false;
			}
			SpeedModifications.ApplySpeedModifications(chara, andSetLocalCache);
			DamageModifications.ApplyDamageModification(chara, andSetLocalCache);
			SizeModifications.SetSizeModification(((Component)chara).gameObject, chara.m_nview, andSetLocalCache, update: true);
			HealthModifications.ForceApplyHealthModifications(chara, andSetLocalCache);
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.ApplyUpdates);
			return true;
		}

		public static List<string> GetPossibleModifiersForType(int modifierType)
		{
			List<string> list = new List<string>();
			switch (modifierType)
			{
			case 0:
				foreach (string key in CreatureModifiersData.ActiveCreatureModifiers.MajorModifiers.Keys)
				{
					list.Add(key);
				}
				break;
			case 1:
				foreach (string key2 in CreatureModifiersData.ActiveCreatureModifiers.MinorModifiers.Keys)
				{
					list.Add(key2);
				}
				break;
			case 2:
				foreach (string key3 in CreatureModifiersData.ActiveCreatureModifiers.BossModifiers.Keys)
				{
					list.Add(key3);
				}
				break;
			default:
				Logger.LogWarning($"Invalid modifier type {modifierType} passed to GetAllPossibleModifiers. Valid types are 0 (Major), 1 (Minor), 2 (Boss).");
				break;
			}
			return list;
		}

		public static Dictionary<string, int> GetAllModifiersForCreature(Character chara)
		{
			Dictionary<string, DataObjects.ModifierType> creatureModifiers = CompositeLazyCache.GetCreatureModifiers(chara);
			if (creatureModifiers == null)
			{
				return null;
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (KeyValuePair<string, DataObjects.ModifierType> item in creatureModifiers)
			{
				dictionary.Add(item.Key.ToString(), (int)item.Value);
			}
			return dictionary;
		}

		public static bool AddModifierToCreature(Character chara, string modifierName, int modifierType, bool update = true)
		{
			if ((Object)(object)chara == (Object)null)
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (CompositeLazyCache.GetAndSetLocalCache(chara) == null)
			{
				return false;
			}
			bool num = CreatureModifiers.AddCreatureModifier(chara, (DataObjects.ModifierType)modifierType, modifierName, update);
			if (num && CompositeLazyCache.IsZOwner(chara))
			{
				ModifierPeerRefresh.SendChanged(chara);
			}
			APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.AddModifier, delegate(ZPackage args)
			{
				args.Write(modifierName);
				args.Write(modifierType);
				args.Write(update);
			});
			return num;
		}

		public static bool RemoveModifierFromCreature(Character chara, string modifierName)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null || string.IsNullOrEmpty(modifierName))
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CompositeLazyCache.IsZOwner(chara))
			{
				APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.RemoveModifier, delegate(ZPackage args)
				{
					args.Write(modifierName);
				});
				return true;
			}
			bool num = CreatureModifiers.RemoveCreatureModifier(chara, modifierName);
			if (num)
			{
				ModifierPeerRefresh.SendChanged(chara);
			}
			return num;
		}

		public static bool SetCreatureModifierConfig(Character chara, string modifierName, Dictionary<string, float> values)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null || values == null || values.Count == 0)
			{
				return false;
			}
			if (string.IsNullOrEmpty(modifierName) || modifierName == CreatureModifiers.NoMods || !CreatureModifiersData.ModifierNamesLookupTable.ContainsName(modifierName))
			{
				Logger.LogWarning("SLS-API: " + modifierName + " is not a modifier; no values were set on " + ((Object)chara).name + ".");
				return false;
			}
			foreach (KeyValuePair<string, float> value in values)
			{
				if (string.IsNullOrEmpty(value.Key) || float.IsNaN(value.Value) || float.IsInfinity(value.Value))
				{
					Logger.LogWarning($"SLS-API: {modifierName} value '{value.Key}' = {value.Value} is not usable; no values were set on {((Object)chara).name}.");
					return false;
				}
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CompositeLazyCache.IsZOwner(chara))
			{
				APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.SetModifierConfig, delegate(ZPackage args)
				{
					args.Write(modifierName);
					APIOwnerRelay.WriteValues(args, values);
				});
				return true;
			}
			if (CreatureModifierOverrides.Set(chara, modifierName, values))
			{
				RefreshIfCarried(chara, modifierName);
			}
			return true;
		}

		public static bool ClearCreatureModifierConfig(Character chara, string modifierName, string key = null)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null || string.IsNullOrEmpty(modifierName))
			{
				return false;
			}
			APIOwnerRelay.ClaimIfUnowned(chara);
			if (!CompositeLazyCache.IsZOwner(chara))
			{
				APIOwnerRelay.SendToOwner(chara, APIOwnerRelay.Op.ClearModifierConfig, delegate(ZPackage args)
				{
					args.Write(modifierName);
					args.Write(key != null);
					args.Write(key ?? string.Empty);
				});
				return true;
			}
			bool num = CreatureModifierOverrides.Clear(chara, modifierName, key);
			if (num)
			{
				RefreshIfCarried(chara, modifierName);
			}
			return num;
		}

		public static Dictionary<string, float> GetCreatureModifierConfig(Character chara, string modifierName, int modifierType = -1)
		{
			if ((Object)(object)chara == (Object)null || string.IsNullOrEmpty(modifierName))
			{
				return null;
			}
			DataObjects.ModifierType type = DataObjects.ModifierType.Major;
			DataObjects.ModifierType type2;
			if (Enum.IsDefined(typeof(DataObjects.ModifierType), modifierType))
			{
				type = (DataObjects.ModifierType)modifierType;
			}
			else if (CompositeLazyCache.TryGetCreatureModifier(chara, modifierName, out type2))
			{
				type = type2;
			}
			return CreatureModifierOverrides.GetEffectiveValues(chara, modifierName, type);
		}

		private static void RefreshIfCarried(Character chara, string modifierName)
		{
			if (CompositeLazyCache.TryGetCreatureModifier(chara, modifierName, out var _))
			{
				ModifierPeerRefresh.SendChanged(chara);
			}
		}

		public static bool SetEnemyHudChangesDisabled(string sourceId, int changes)
		{
			return EnemyHudChanges.Set(sourceId, changes);
		}

		public static int GetDisabledEnemyHudChanges()
		{
			EnemyHudChanges.Refresh();
			return (int)EnemyHudChanges.Disabled;
		}

		public static Dictionary<string, object> GetCreatureHudInfo(Character chara)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null || chara.IsPlayer())
			{
				return null;
			}
			try
			{
				return UIHudControl.GetHudInfo(chara);
			}
			catch (Exception ex)
			{
				Logger.LogDebug("SLS-API: no hud info for " + ((Object)chara).name + " yet: " + ex.Message);
				return null;
			}
		}

		public static float GetCreatureEvolveProgress(Character chara)
		{
			if ((Object)(object)chara == (Object)null || (Object)(object)chara.m_nview == (Object)null || chara.m_nview.GetZDO() == null)
			{
				return -1f;
			}
			try
			{
				return UIHudControl.GetEvolveProgress(chara);
			}
			catch (Exception ex)
			{
				Logger.LogDebug("SLS-API: no evolve progress for " + ((Object)chara).name + " yet: " + ex.Message);
				return -1f;
			}
		}

		public static bool AddNewModifierToSLS(int modifierID, string modifier_name, Delegate setupMethod = null, float selectionWeight = 10f, float basepower = 0f, float perlevelpower = 0f, Dictionary<Biome, List<string>> biomeConfig = null, int namingStyle = 2, string name_suffixes = null, string name_prefixes = null, int visualStyle = 0, Sprite starIcon = null, GameObject visualEffect = null, List<string> allowed_creatures = null, List<string> unallowed_creatures = null, List<Biome> allowed_biomes = null)
		{
			if (CreatureModifiersData.ModifierNamesLookupTable.ContainsID(modifierID))
			{
				Logger.LogWarning($"Modifier ID {modifierID} already exists as {CreatureModifiersData.ModifierNamesLookupTable.GetValue(modifierID)}, please choose a different ID");
				return false;
			}
			CreatureModifiersData.ModifierNamesLookupTable.AddValue(modifier_name, modifierID);
			DataObjects.CreatureModifierDefinition creatureModifierDefinition = new DataObjects.CreatureModifierDefinition();
			if ((Object)(object)starIcon != (Object)null)
			{
				creatureModifierDefinition.StarVisualAPI = starIcon;
				creatureModifierDefinition.StarVisual = ((Object)starIcon).name;
			}
			if ((Object)(object)visualEffect != (Object)null)
			{
				creatureModifierDefinition.VisualEffectAPI = visualEffect;
				creatureModifierDefinition.VisualEffect = ((Object)visualEffect).name;
			}
			if ((object)setupMethod != null)
			{
				creatureModifierDefinition.SetupEvent = setupMethod;
			}
			if (name_suffixes != null)
			{
				creatureModifierDefinition.NameSuffix = name_suffixes;
			}
			if (name_prefixes != null)
			{
				creatureModifierDefinition.NamePrefix = name_prefixes;
			}
			if (namingStyle > 2 || namingStyle < 0)
			{
				namingStyle = 2;
			}
			creatureModifierDefinition.NamingConvention = (DataObjects.NameSelectionStyle)namingStyle;
			if (visualStyle > 3 || visualStyle < 0)
			{
				visualStyle = 0;
			}
			creatureModifierDefinition.VisualEffectStyle = (DataObjects.VisualEffectStyle)visualStyle;
			DataObjects.CreatureModifierConfiguration creatureModifierConfiguration = new DataObjects.CreatureModifierConfiguration();
			creatureModifierConfiguration.Config = new DataObjects.CreatureModConfig
			{
				BasePower = basepower,
				PerlevelPower = perlevelpower,
				BiomeObjects = biomeConfig
			};
			creatureModifierConfiguration.SelectionWeight = selectionWeight;
			if (allowed_creatures != null)
			{
				creatureModifierConfiguration.AllowedCreatures = allowed_creatures;
			}
			if (unallowed_creatures != null)
			{
				creatureModifierConfiguration.UnallowedCreatures = unallowed_creatures;
			}
			if (allowed_biomes != null)
			{
				creatureModifierConfiguration.AllowedBiomes = allowed_biomes;
			}
			CreatureModifiersData.RegisterAPIModifier(modifier_name, creatureModifierDefinition, creatureModifierConfiguration);
			return true;
		}

		public static bool RegisterLocationResetTarget(string prefabName, string sourceId, float resetHours, string resetSchedule, int mode, bool resetTerrain, float terrainRadius, float extraTerrainRadius, bool resetInterior, float minDistance, float maxDistance, bool enabled, Action<bool> onResult)
		{
			return RelayScalar(LocationResetNetwork.Op.Register, new Dictionary<string, object>
			{
				{
					"name",
					prefabName ?? ""
				},
				{
					"sourceId",
					sourceId ?? ""
				},
				{ "resetHours", resetHours },
				{
					"resetSchedule",
					resetSchedule ?? ""
				},
				{ "mode", mode },
				{ "resetTerrain", resetTerrain },
				{ "terrainRadius", terrainRadius },
				{ "extraTerrainRadius", extraTerrainRadius },
				{ "resetInterior", resetInterior },
				{ "minDistance", minDistance },
				{ "maxDistance", maxDistance },
				{ "enabled", enabled }
			}, () => LocalRegister(prefabName, sourceId, resetHours, resetSchedule, mode, resetTerrain, terrainRadius, extraTerrainRadius, resetInterior, minDistance, maxDistance, enabled), onResult, failure: false, 0f);
		}

		internal static bool LocalRegister(string prefabName, string sourceId, float resetHours, string resetSchedule, int mode, bool resetTerrain, float terrainRadius, float extraTerrainRadius, bool resetInterior, float minDistance, float maxDistance, bool enabled)
		{
			if (mode > 1 || mode < 0)
			{
				Logger.LogLocationResetWarning($"'{sourceId}' registered '{prefabName}' with mode {mode}; " + "valid values are 0 (Full) and 1 (TerrainOnly). Using Full.");
				mode = 0;
			}
			DataObjects.LocationResetEntry entry = new DataObjects.LocationResetEntry
			{
				Enabled = enabled,
				ResetHours = ((resetHours > 0f) ? new float?(resetHours) : ((float?)null)),
				ResetSchedule = (string.IsNullOrWhiteSpace(resetSchedule) ? null : resetSchedule.Trim()),
				Mode = (DataObjects.LocationResetMode)mode,
				ResetTerrain = resetTerrain,
				TerrainRadius = ((terrainRadius > 0f) ? new float?(terrainRadius) : ((float?)null)),
				ExtraTerrainRadius = ((extraTerrainRadius > 0f) ? new float?(extraTerrainRadius) : ((float?)null)),
				ResetInterior = resetInterior,
				Protection = null
			};
			return LocationResetData.RegisterAPIResetTarget(prefabName, sourceId, entry, minDistance, maxDistance);
		}

		public static bool UnregisterLocationResetTarget(string prefabName, string sourceId, Action<bool> onResult)
		{
			return RelayScalar(LocationResetNetwork.Op.Unregister, new Dictionary<string, object>
			{
				{
					"name",
					prefabName ?? ""
				},
				{
					"sourceId",
					sourceId ?? ""
				}
			}, () => LocationResetData.UnregisterAPIResetTarget(prefabName, sourceId), onResult, failure: false, 0f);
		}

		public static bool GetRegisteredLocationResetTargets(string sourceId, Action<List<string>> onResult)
		{
			return RelayScalar(LocationResetNetwork.Op.RegisteredNames, new Dictionary<string, object> { 
			{
				"sourceId",
				sourceId ?? ""
			} }, () => LocationResetData.GetAPIRegisteredNames(sourceId), onResult, new List<string>(), 0f);
		}

		public static bool GetLocationResetTargetInfo(string prefabName, Action<Dictionary<string, object>> onResult)
		{
			return RelayDictionary(LocationResetNetwork.Op.TargetInfo, new Dictionary<string, object> { 
			{
				"name",
				prefabName ?? ""
			} }, () => LocalTargetInfo(prefabName), onResult, 0f);
		}

		internal static Dictionary<string, object> LocalTargetInfo(string prefabName)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>
			{
				{
					"name",
					prefabName ?? ""
				},
				{ "known", false },
				{ "configured", false },
				{ "enabled", false },
				{ "source", "none" }
			};
			if (string.IsNullOrWhiteSpace(prefabName))
			{
				return dictionary;
			}
			string text = prefabName.Trim();
			int stableHashCode = StringExtensionMethods.GetStableHashCode(text);
			dictionary["name"] = text;
			dictionary["known"] = LocationResetData.IsKnownTargetName(stableHashCode);
			dictionary["source"] = LocationResetData.DescribeResolutionSource(text);
			dictionary["hardBlocked"] = LocationResetData.HardBlockedLocations.Contains(text);
			dictionary["registeredByAPI"] = LocationResetData.TryGetAPIRegistration(text, out var registration);
			dictionary["registeredBy"] = ((registration != null) ? registration.SourceId : "");
			LocationResetData.ResolvedResetEntry entry;
			bool flag = LocationResetData.TryGetLocationEntry(stableHashCode, out entry);
			LocationResetData.ResolvedResetEntry entry2;
			bool flag2 = LocationResetData.TryGetVegetationEntry(stableHashCode, out entry2);
			if (entry == null)
			{
				entry = entry2;
			}
			dictionary["isLocation"] = flag;
			dictionary["isVegetation"] = flag2;
			dictionary["configured"] = entry != null;
			if (entry == null)
			{
				return dictionary;
			}
			dictionary["enabled"] = entry.Enabled;
			dictionary["groupName"] = entry.GroupName ?? "";
			dictionary["resetSeconds"] = entry.ResetSeconds;
			dictionary["schedule"] = ((entry.Schedule != null) ? entry.Schedule.Expression : "");
			dictionary["mode"] = (int)entry.Mode;
			dictionary["resetTerrain"] = entry.ResetTerrain;
			dictionary["terrainRadius"] = entry.TerrainRadius;
			dictionary["extraTerrainRadius"] = entry.ExtraTerrainRadius;
			dictionary["resetInterior"] = entry.ResetInterior;
			return dictionary;
		}

		public static bool IsLocationResetReady(Action<bool> onResult)
		{
			return RelayScalar(LocationResetNetwork.Op.Ready, null, LocalReady, onResult, failure: false, 0f);
		}

		internal static bool LocalReady()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return false;
			}
			if (LocationResetData.BlockedByModConflict)
			{
				return false;
			}
			return LocationResetControl.Ready;
		}

		public static bool GetLocationResetStatus(Action<Dictionary<string, object>> onResult)
		{
			return RelayDictionary(LocationResetNetwork.Op.Status, null, LocalStatus, onResult, 0f);
		}

		internal static Dictionary<string, object> LocalStatus()
		{
			return new Dictionary<string, object>
			{
				{ "available", true },
				{
					"isServer",
					(Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()
				},
				{
					"ready",
					LocationResetControl.Ready
				},
				{
					"sweepAllowed",
					LocationResetControl.SweepAllowed
				},
				{
					"masterSwitchEnabled",
					ValConfig.EnableLocationReset.Value
				},
				{
					"configEnabled",
					LocationResetData.ConfigEnabled
				},
				{
					"blockedByModConflict",
					LocationResetData.BlockedByModConflict
				},
				{
					"resetRunning",
					LocationResetControl.ManualResetRunning
				},
				{
					"trackedZones",
					LocationResetState.TrackedZoneCount
				},
				{
					"generatedZones",
					((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_generatedZones.Count : 0
				},
				{
					"sweepFloorSeconds",
					LocationResetData.MinEnabledIntervalSeconds
				},
				{
					"apiRegistrations",
					LocationResetData.APIAdded.Count
				},
				{
					"clientMaxRadius",
					ValConfig.ClientLocationResetMaxRadius.Value
				},
				{
					"clientMaxDistance",
					ValConfig.ClientLocationResetMaxDistance.Value
				},
				{
					"clientCooldownSeconds",
					ValConfig.ClientLocationResetCooldownSeconds.Value
				}
			};
		}

		public static bool IsKnownResetTargetName(string prefabName, Action<bool> onResult)
		{
			return RelayScalar(LocationResetNetwork.Op.IsKnownName, new Dictionary<string, object> { 
			{
				"name",
				prefabName ?? ""
			} }, () => LocalIsKnownName(prefabName), onResult, failure: false, 0f);
		}

		internal static bool LocalIsKnownName(string prefabName)
		{
			if (string.IsNullOrWhiteSpace(prefabName))
			{
				return false;
			}
			return LocationResetData.IsKnownTargetName(StringExtensionMethods.GetStableHashCode(prefabName.Trim()));
		}

		public static bool GetLocationLastReset(string locationName, Vector3 center, float radius, Action<long> onResult)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return RelayScalar(LocationResetNetwork.Op.LastReset, LocationArgs(locationName, center, radius), () => LocationResetQuery.GetLocationLastReset(locationName, center, radius), onResult, -1L, 0f);
		}

		public static bool GetSecondsUntilLocationReset(string locationName, Vector3 center, float radius, Action<double> onResult)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return RelayScalar(LocationResetNetwork.Op.SecondsUntilDue, LocationArgs(locationName, center, radius), () => LocationResetQuery.GetSecondsUntilDue(locationName, center, radius), onResult, -1.0, 0f);
		}

		public static bool GetLocationResetInfo(string locationName, Vector3 center, float radius, Action<Dictionary<string, object>> onResult)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return RelayDictionary(LocationResetNetwork.Op.LocationInfo, LocationArgs(locationName, center, radius), () => LocationResetQuery.GetLocationInfo(locationName, center, radius), onResult, 0f);
		}

		public static bool GetChunkResetInfo(Vector3 position, bool includePrefabs, Action<Dictionary<string, object>> onResult)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, object> dictionary = PositionArgs(position);
			dictionary["includePrefabs"] = includePrefabs;
			return RelayDictionary(LocationResetNetwork.Op.ChunkInfo, dictionary, () => LocationResetQuery.GetChunkInfo(position, includePrefabs), onResult, 0f);
		}

		public static bool ResetNamedLocation(string locationName, Vector3 center, float radius, int safety, bool resetAllMatches, float safeWaitSeconds, bool includeDetail, Action<Dictionary<string, object>> onComplete)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(locationName))
			{
				Logger.LogLocationResetWarning("SLS-API: ResetNamedLocation needs a location name.");
				Deliver(onComplete, ResetSummary.RefusalDictionary("no_name", "ResetNamedLocation needs a location name."), LocationResetNetwork.Op.ResetNamed);
				return false;
			}
			Dictionary<string, object> dictionary = ResetArgs(center, radius, safety, safeWaitSeconds, includeDetail);
			dictionary["name"] = locationName.Trim();
			dictionary["resetAllMatches"] = resetAllMatches;
			return RelayReset(LocationResetNetwork.Op.ResetNamed, dictionary, safeWaitSeconds, onComplete, () => LocationResetControl.RequestReset(new LocationResetControl.ResetRequest
			{
				Center = center,
				Radius = radius,
				Safety = ClampSafety(safety),
				LocationName = locationName.Trim(),
				ResetAllMatches = resetAllMatches,
				SafeWaitSeconds = safeWaitSeconds,
				IncludeDetail = includeDetail,
				Source = "API reset '" + locationName.Trim() + "'"
			}, null, onComplete));
		}

		public static bool ResetLocationsInRadius(Vector3 center, float radius, int safety, float safeWaitSeconds, bool includeDetail, Action<Dictionary<string, object>> onComplete)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			return RelayReset(LocationResetNetwork.Op.ResetRadius, ResetArgs(center, radius, safety, safeWaitSeconds, includeDetail), safeWaitSeconds, onComplete, () => LocationResetControl.RequestReset(new LocationResetControl.ResetRequest
			{
				Center = center,
				Radius = radius,
				Safety = ClampSafety(safety),
				SafeWaitSeconds = safeWaitSeconds,
				IncludeDetail = includeDetail,
				Source = $"API reset r={radius:0}"
			}, null, onComplete));
		}

		private static int ClampSafety(int safety)
		{
			return (safety == 1) ? 1 : 0;
		}

		private static Dictionary<string, object> PositionArgs(Vector3 position)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			return new Dictionary<string, object>
			{
				{ "x", position.x },
				{ "y", position.y },
				{ "z", position.z }
			};
		}

		private static Dictionary<string, object> LocationArgs(string locationName, Vector3 center, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, object> dictionary = PositionArgs(center);
			dictionary["name"] = locationName ?? "";
			dictionary["radius"] = radius;
			return dictionary;
		}

		private static Dictionary<string, object> ResetArgs(Vector3 center, float radius, int safety, float safeWaitSeconds, bool includeDetail)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, object> dictionary = PositionArgs(center);
			dictionary["radius"] = radius;
			dictionary["safety"] = safety;
			dictionary["safeWaitSeconds"] = safeWaitSeconds;
			dictionary["includeDetail"] = includeDetail;
			return dictionary;
		}

		private static bool RelayScalar<T>(LocationResetNetwork.Op op, Dictionary<string, object> args, Func<T> local, Action<T> onResult, T failure, float timeout)
		{
			if (LocationResetNetwork.IsServer)
			{
				T value = local();
				Deliver(onResult, value, op);
				return true;
			}
			if (LocationResetNetwork.Send(op, args, timeout, delegate(Dictionary<string, object> result)
			{
				Deliver(onResult, Unwrap(result, failure, op), op);
			}))
			{
				return true;
			}
			Deliver(onResult, failure, op);
			return false;
		}

		private static bool RelayDictionary(LocationResetNetwork.Op op, Dictionary<string, object> args, Func<Dictionary<string, object>> local, Action<Dictionary<string, object>> onResult, float timeout)
		{
			if (LocationResetNetwork.IsServer)
			{
				Dictionary<string, object> value = local();
				Deliver(onResult, value, op);
				return true;
			}
			if (LocationResetNetwork.Send(op, args, timeout, delegate(Dictionary<string, object> result)
			{
				LogIfRefused(result, op);
				Deliver(onResult, result, op);
			}))
			{
				return true;
			}
			Deliver(onResult, NoConnection(op), op);
			return false;
		}

		private static bool RelayReset(LocationResetNetwork.Op op, Dictionary<string, object> args, float safeWaitSeconds, Action<Dictionary<string, object>> onComplete, Func<bool> local)
		{
			if (LocationResetNetwork.IsServer)
			{
				return local();
			}
			float timeoutSeconds = Mathf.Max(safeWaitSeconds, 300f) + 60f;
			if (LocationResetNetwork.Send(op, args, timeoutSeconds, delegate(Dictionary<string, object> result)
			{
				LogIfRefused(result, op);
				Deliver(onComplete, result, op);
			}))
			{
				return true;
			}
			Deliver(onComplete, NoConnection(op), op);
			return false;
		}

		private static Dictionary<string, object> NoConnection(LocationResetNetwork.Op op)
		{
			return ResetSummary.RefusalDictionary("no_connection", $"{op} could not be sent: this client has no server connection.");
		}

		private static T Unwrap<T>(Dictionary<string, object> result, T failure, LocationResetNetwork.Op op)
		{
			if (LogIfRefused(result, op))
			{
				return failure;
			}
			if (result == null || !result.TryGetValue("value", out var value))
			{
				return failure;
			}
			if (value == null)
			{
				return failure;
			}
			if (value is T)
			{
				return (T)value;
			}
			try
			{
				return (T)Convert.ChangeType(value, typeof(T));
			}
			catch (Exception)
			{
				return failure;
			}
		}

		private static bool LogIfRefused(Dictionary<string, object> result, LocationResetNetwork.Op op)
		{
			if (result == null)
			{
				return false;
			}
			if (!result.TryGetValue("outcome", out var value))
			{
				return false;
			}
			if (Convert.ToString(value) != "refused")
			{
				return false;
			}
			result.TryGetValue("reason", out var value2);
			result.TryGetValue("refusalCode", out var value3);
			Logger.LogLocationResetWarning($"SLS-API: {op} was refused [{value3}] - {value2}");
			return true;
		}

		private static void Deliver<T>(Action<T> onResult, T value, LocationResetNetwork.Op op)
		{
			if (onResult == null)
			{
				return;
			}
			try
			{
				onResult(value);
			}
			catch (Exception arg)
			{
				Logger.LogLocationResetWarning($"A mod's {op} callback threw and was ignored: {arg}");
			}
		}
	}
	internal static class BossNightSpawns
	{
		[HarmonyPatch(typeof(SpawnSystem), "UpdateSpawnList")]
		public static class SkipTurnedOffNightSpawns
		{
			private static readonly List<SpawnData> switchedOff = new List<SpawnData>();

			private static void Prefix(List<SpawnData> spawners, bool eventSpawners)
			{
				if (eventSpawners || spawners == null || !AnyTurnedOff())
				{
					return;
				}
				foreach (SpawnData spawner in spawners)
				{
					if (spawner != null && spawner.m_enabled && IsBossNightSpawn(spawner, out var toggle) && !toggle.Value)
					{
						spawner.m_enabled = false;
						switchedOff.Add(spawner);
					}
				}
			}

			private static void Finalizer()
			{
				if (switchedOff.Count == 0)
				{
					return;
				}
				foreach (SpawnData item in switchedOff)
				{
					item.m_enabled = true;
				}
				switchedOff.Clear();
			}
		}

		internal static readonly Dictionary<string, string> VanillaSpawns = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "defeated_eikthyr", "Greydwarfs in the Meadows" },
			{ "defeated_gdking", "Greydwarf brutes and shamans in the Meadows, and Draugr in fog across the Meadows, Black Forest, Mountain and Plains" },
			{ "defeated_bonemass", "Skeletons across the Meadows, Black Forest, Swamp, Mountain and Plains" },
			{ "defeated_dragon", "" },
			{ "defeated_goblinking", "Fulings across the Meadows, Black Forest and Mountain" },
			{ "defeated_queen", "Seekers, Seeker broods and Ticks across the Meadows, Black Forest, Mountain and Plains" },
			{ "defeated_fader", "" }
		};

		private static Dictionary<string, ConfigEntry<bool>> toggles;

		private static Dictionary<string, ConfigEntry<bool>> Toggles
		{
			get
			{
				if (toggles == null)
				{
					toggles = new Dictionary<string, ConfigEntry<bool>>(StringComparer.OrdinalIgnoreCase)
					{
						{
							"defeated_eikthyr",
							ValConfig.EikthyrNightSpawns
						},
						{
							"defeated_gdking",
							ValConfig.ElderNightSpawns
						},
						{
							"defeated_bonemass",
							ValConfig.BonemassNightSpawns
						},
						{
							"defeated_dragon",
							ValConfig.ModerNightSpawns
						},
						{
							"defeated_goblinking",
							ValConfig.YagluthNightSpawns
						},
						{
							"defeated_queen",
							ValConfig.QueenNightSpawns
						},
						{
							"defeated_fader",
							ValConfig.FaderNightSpawns
						}
					};
				}
				return toggles;
			}
		}

		internal static string SettingDescription(string bossKey, string bossName)
		{
			string value;
			string text = ((VanillaSpawns.TryGetValue(bossKey, out value) && value.Length > 0) ? ("In vanilla that is " + value + ".") : "None are known in vanilla, but other mods can add them.");
			return "Allows the creatures that only spawn at night once " + bossName + " is defeated. " + text + " Turn off to stop them; any already out still leave at dawn. Nothing else the boss unlocks is affected.";
		}

		internal static ConfigEntry<bool> ToggleFor(string bossKey)
		{
			if (string.IsNullOrEmpty(bossKey))
			{
				return null;
			}
			if (!Toggles.TryGetValue(bossKey, out var value))
			{
				return null;
			}
			return value;
		}

		private static bool AnyTurnedOff()
		{
			foreach (ConfigEntry<bool> value in Toggles.Values)
			{
				if (value != null && !value.Value)
				{
					return true;
				}
			}
			return false;
		}

		internal static bool IsBossNightSpawn(SpawnData spawn, out ConfigEntry<bool> toggle)
		{
			toggle = null;
			if (spawn == null || spawn.m_spawnAtDay || !spawn.m_spawnAtNight || string.IsNullOrEmpty(spawn.m_requiredGlobalKey))
			{
				return false;
			}
			toggle = ToggleFor(spawn.m_requiredGlobalKey);
			if (toggle != null && (Object)(object)spawn.m_prefab != (Object)null)
			{
				return (Object)(object)spawn.m_prefab.GetComponent<Character>() != (Object)null;
			}
			return false;
		}

		internal static bool TryGetLiveSpawns(string bossKey, out List<SpawnData> spawns)
		{
			spawns = new List<SpawnData>();
			SpawnSystem val = ((SpawnSystem.m_instances.Count > 0) ? SpawnSystem.m_instances[0] : null);
			if ((Object)(object)val == (Object)null && (Object)(object)ZoneSystem.instance != (Object)null && (Object)(object)ZoneSystem.instance.m_zoneCtrlPrefab != (Object)null)
			{
				val = ZoneSystem.instance.m_zoneCtrlPrefab.GetComponent<SpawnSystem>();
			}
			if ((Object)(object)val == (Object)null || val.m_spawnLists == null)
			{
				return false;
			}
			foreach (SpawnSystemList spawnList in val.m_spawnLists)
			{
				if ((Object)(object)spawnList == (Object)null || spawnList.m_spawners == null)
				{
					continue;
				}
				foreach (SpawnData spawner in spawnList.m_spawners)
				{
					if (spawner.m_enabled && IsBossNightSpawn(spawner, out var _) && string.Equals(spawner.m_requiredGlobalKey, bossKey, StringComparison.OrdinalIgnoreCase))
					{
						spawns.Add(spawner);
					}
				}
			}
			return true;
		}
	}
	internal static class BossPhases
	{
		[HarmonyPatch(typeof(Character), "OnDeath")]
		public static class CarryLevelToNextPhase
		{
			private static void Prefix(Character __instance)
			{
				pendingPhase = null;
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner() && NextPhase.TryGetValue(Utils.GetPrefabName(((Component)__instance).gameObject), out var value))
				{
					int num = __instance.m_nview.GetZDO().GetInt(DataObjects.SLS_PHASE_LEVEL, 0);
					if (num <= 0)
					{
						num = __instance.GetLevel();
					}
					pendingPhase = value;
					pendingLevel = num;
				}
			}

			private static void Finalizer()
			{
				pendingPhase = null;
			}
		}

		private static readonly HashSet<string> PinnedPrefabs = new HashSet<string> { "FrozenKing_p2" };

		private static readonly Dictionary<string, string> NextPhase = new Dictionary<string, string>
		{
			{ "FrozenKing", "FrozenKing_p2" },
			{ "FrozenKing_p2", "FrozenKing_p3" }
		};

		private const string AspectPrefix = "Aspect_";

		private static string pendingPhase;

		private static int pendingLevel;

		internal static bool IsPinned(Character chara)
		{
			if ((Object)(object)chara != (Object)null)
			{
				return PinnedPrefabs.Contains(Utils.GetPrefabName(((Component)chara).gameObject));
			}
			return false;
		}

		internal static bool IsAspect(Character chara)
		{
			if ((Object)(object)chara != (Object)null)
			{
				return Utils.GetPrefabName(((Component)chara).gameObject).StartsWith("Aspect_", StringComparison.Ordinal);
			}
			return false;
		}

		internal static void TakeCarriedLevel(Character chara)
		{
			if (pendingPhase != null && !((Object)(object)chara == (Object)null) && !((Object)(object)chara.m_nview == (Object)null) && chara.m_nview.IsValid() && chara.m_nview.IsOwner() && !(Utils.GetPrefabName(((Component)chara).gameObject) != pendingPhase))
			{
				ZDO zDO = chara.m_nview.GetZDO();
				zDO.Set(DataObjects.SLS_PHASE_LEVEL, pendingLevel);
				if (!IsPinned(chara) && zDO.GetInt(ZDOVars.s_level, 0) <= 0)
				{
					zDO.Set(ZDOVars.s_level, pendingLevel, false);
					chara.m_level = pendingLevel;
				}
			}
		}
	}
	public static class Colorization
	{
		[HarmonyPatch(typeof(LevelEffects), "SetupLevelVisualization")]
		public static class PreventDefaultLevelSetup
		{
			public static bool Prefix()
			{
				return false;
			}
		}

		internal static DataObjects.CreatureColorizationSettings defaultColorizationSettings = new DataObjects.CreatureColorizationSettings
		{
			CharacterSpecificColorization = ColorizationData.characterColorizationData,
			DefaultLevelColorization = ColorizationData.defaultColorizationData,
			CharacterColorGenerators = ColorizationData.defaultColorGenerators
		};

		public static DataObjects.CreatureColorizationSettings creatureColorizationSettings = defaultColorizationSettings;

		public static List<Color> mapRingColors = new List<Color>();

		public static List<Color> zoneOverlayColors = new List<Color>();

		public static readonly Dictionary<string, string> defaultColors = new Dictionary<string, string>
		{
			{ "Red", "#ff1a1a" },
			{ "Orange", "#ff9933" },
			{ "Yellow", "#ffff1a" },
			{ "Green", "#50f83a" },
			{ "Teal", "#18e7a9" },
			{ "Blue", "#00abff" },
			{ "Purple", "#c966ff" },
			{ "Pink", "#ff4dcf" },
			{ "Gray", "#999999" },
			{ "Brown", "#b37700" },
			{ "Black", "#333333" },
			{ "White", "#f2f2f2" },
			{ "LightYellow", "#ffff99" },
			{ "LightOrange", "#ffc266" },
			{ "DarkOrange", "#cc6600" },
			{ "LightRed", "#ff6666" },
			{ "DarkRed", "#b30000" },
			{ "LightPurple", "#e0b3ff" },
			{ "DarkPurple", "#8000b3" }
		};

		public static DataObjects.ColorDef defaultColorization = new DataObjects.ColorDef
		{
			Hue = 0f,
			Saturation = 0f,
			Value = 0f,
			IsEmissive = false
		};

		private const string SLSInstancedMaterialSuffix = " (SLSColor)";

		internal static void ApplyLoaded(DataObjects.CreatureColorizationSettings parsed)
		{
			if (parsed.DefaultLevelColorization == null)
			{
				parsed.DefaultLevelColorization = new Dictionary<int, DataObjects.ColorDef>();
			}
			Colorization.creatureColorizationSettings = parsed;
			foreach (KeyValuePair<int, DataObjects.ColorDef> item in defaultColorizationSettings.DefaultLevelColorization)
			{
				if (!Enumerable.Contains(Colorization.creatureColorizationSettings.DefaultLevelColorization.Keys, item.Key))
				{
					Colorization.creatureColorizationSettings.DefaultLevelColorization.Add(item.Key, item.Value);
				}
			}
			if (Colorization.creatureColorizationSettings.CharacterColorGenerators != null)
			{
				Logger.LogInfo("Running color generators");
				DataObjects.CreatureColorizationSettings creatureColorizationSettings = Colorization.creatureColorizationSettings;
				if (creatureColorizationSettings.CharacterSpecificColorization == null)
				{
					Dictionary<string, Dictionary<int, DataObjects.ColorDef>> dictionary = (creatureColorizationSettings.CharacterSpecificColorization = new Dictionary<string, Dictionary<int, DataObjects.ColorDef>>());
				}
				foreach (KeyValuePair<string, List<DataObjects.ColorRangeDef>> characterColorGenerator in Colorization.creatureColorizationSettings.CharacterColorGenerators)
				{
					Logger.LogInfo("Building color range for " + characterColorGenerator.Key);
					foreach (DataObjects.ColorRangeDef item2 in characterColorGenerator.Value)
					{
						BuildAddColorRange(characterColorGenerator.Key, item2);
					}
				}
				if (ValConfig.OutputColorizationGeneratorsData.Value)
				{
					File.WriteAllText(Path.Combine(Paths.ConfigPath, "StarLevelSystem", "DebugGeneratedColorValues.yaml"), DataObjects.yamlSerializer.Serialize((object)Colorization.creatureColorizationSettings));
				}
			}
			Logger.LogInfo("Updated ColorizationSettings.");
			Character[] array = Resources.FindObjectsOfTypeAll<Character>();
			foreach (Character val in array)
			{
				if (val.m_level > 1)
				{
					DataObjects.CharacterCacheEntry cacheEntry = CompositeLazyCache.GetCacheEntry(val);
					if (cacheEntry != null)
					{
						cacheEntry.Colorization = DetermineCharacterColorization(val, val.m_level);
						CompositeLazyCache.UpdateCharacterCacheEntry(val, cacheEntry);
						ApplyColorizationWithoutLevelEffects(((Component)val).gameObject, cacheEntry.Colorization);
					}
				}
			}
		}

		public static void ApplyLevelVisual(Character charc)
		{
			LevelEffects componentInChildren = ((Component)charc).gameObject.GetComponentInChildren<LevelEffects>();
			if (!((Object)(object)componentInChildren == (Object)null) && componentInChildren.m_levelSetups != null && componentInChildren.m_levelSetups.Count > 0)
			{
				LevelSetup val = componentInChildren.m_levelSetups[Random.Range(0, componentInChildren.m_levelSetups.Count)];
				if ((Object)(object)val.m_enableObject != (Object)null)
				{
					val.m_enableObject.SetActive(true);
				}
			}
		}

		internal static DataObjects.ColorDef DetermineCharacterColorization(Character cgo, int level)
		{
			if ((Object)(object)cgo == (Object)null)
			{
				return null;
			}
			string prefabName = Utils.GetPrefabName(((Component)cgo).gameObject);
			if (creatureColorizationSettings.CharacterSpecificColorization != null && creatureColorizationSettings.CharacterSpecificColorization.ContainsKey(prefabName) && creatureColorizationSettings.CharacterSpecificColorization[prefabName].ContainsKey(level - 1) && creatureColorizationSettings.CharacterSpecificColorization[prefabName].TryGetValue(level - 1, out var value))
			{
				return value;
			}
			return GetDefaultColorization(level - 1);
		}

		internal static void ApplyColorizationWithoutLevelEffects(GameObject cgo, DataObjects.ColorDef colorization)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if (!ValConfig.EnableColorization.Value || colorization == null)
			{
				return;
			}
			LevelSetup val = colorization.ToLevelEffect();
			try
			{
				SkinnedMeshRenderer[] componentsInChildren = cgo.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val2 in componentsInChildren)
				{
					Material[] sharedMaterials = ((Renderer)val2).sharedMaterials;
					if (sharedMaterials.Length == 0)
					{
						continue;
					}
					Material val3 = sharedMaterials[0];
					if (!((Object)(object)val3 == (Object)null))
					{
						if (!((Object)val3).name.EndsWith(" (SLSColor)"))
						{
							val3 = new Material(val3);
							Material obj = val3;
							((Object)obj).name = ((Object)obj).name + " (SLSColor)";
							sharedMaterials[0] = val3;
							((Renderer)val2).sharedMaterials = sharedMaterials;
						}
						val3.SetFloat("_Hue", val.m_hue);
						val3.SetFloat("_Saturation", val.m_saturation);
						val3.SetFloat("_Value", val.m_value);
						if (val.m_setEmissiveColor)
						{
							val3.SetColor("_EmissionColor", val.m_emissiveColor);
						}
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError($"Exception while colorizing {arg}");
			}
		}

		internal static void BuildAddColorRange(string creatureKey, DataObjects.ColorRangeDef colorGen)
		{
			float num = Mathf.Abs(colorGen.EndColorDef.Hue) + Mathf.Abs(colorGen.StartColorDef.Hue);
			Mathf.Clamp(num, 0f, 2f);
			float num2 = Mathf.Abs(colorGen.EndColorDef.Saturation) + Mathf.Abs(colorGen.StartColorDef.Saturation);
			Mathf.Clamp(num2, 0f, 2f);
			float num3 = Mathf.Abs(colorGen.EndColorDef.Value) + Mathf.Abs(colorGen.StartColorDef.Value);
			Mathf.Clamp(num3, 0f, 2f);
			int num4 = colorGen.RangeEnd - colorGen.RangeStart;
			float num5 = num / (float)num4;
			float num6 = num2 / (float)num4;
			float num7 = num3 / (float)num4;
			int num8 = ((!(colorGen.StartColorDef.Hue > colorGen.EndColorDef.Hue)) ? 1 : (-1));
			int num9 = ((!(colorGen.StartColorDef.Saturation > colorGen.EndColorDef.Saturation)) ? 1 : (-1));
			int num10 = ((!(colorGen.StartColorDef.Value > colorGen.EndColorDef.Value)) ? 1 : (-1));
			if (colorGen.CharacterSpecific && !creatureColorizationSettings.CharacterSpecificColorization.ContainsKey(creatureKey))
			{
				creatureColorizationSettings.CharacterSpecificColorization.Add(creatureKey, new Dictionary<int, DataObjects.ColorDef>());
			}
			int num11 = colorGen.RangeStart;
			int num12 = 0;
			while (num11 < colorGen.RangeEnd + 1)
			{
				DataObjects.ColorDef value = new DataObjects.ColorDef
				{
					Hue = colorGen.StartColorDef.Hue + num5 * (float)num12 * (float)num8,
					Saturation = colorGen.StartColorDef.Saturation + num6 * (float)num12 * (float)num9,
					Value = colorGen.StartColorDef.Value + num7 * (float)num12 * (float)num10,
					IsEmissive = false
				};
				if (colorGen.CharacterSpecific)
				{
					if (!creatureColorizationSettings.CharacterSpecificColorization.ContainsKey(creatureKey))
					{
						creatureColorizationSettings.CharacterSpecificColorization.Add(creatureKey, new Dictionary<int, DataObjects.ColorDef>());
					}
					if (creatureColorizationSettings.CharacterSpecificColorization[creatureKey].ContainsKey(num11))
					{
						if (colorGen.OverwriteExisting)
						{
							creatureColorizationSettings.CharacterSpecificColorization[creatureKey][num11] = value;
						}
					}
					else
					{
						creatureColorizationSettings.CharacterSpecificColorization[creatureKey].Add(num11, value);
					}
				}
				else if (creatureColorizationSettings.DefaultLevelColorization.ContainsKey(num11))
				{
					if (colorGen.OverwriteExisting)
					{
						creatureColorizationSettings.DefaultLevelColorization[num11] = value;
					}
				}
				else
				{
					creatureColorizationSettings.DefaultLevelColorization.Add(num11, value);
				}
				num11++;
				num12++;
			}
		}

		internal static DataObjects.ColorDef GetDefaultColorization(int level)
		{
			if (creatureColorizationSettings.DefaultLevelColorization.ContainsKey(level))
			{
				return creatureColorizationSettings.DefaultLevelColorization[level];
			}
			return defaultColorization;
		}

		public static void UpdateMapColorSelection()
		{
			ParseColorOptions(ValConfig.DistanceRingColorOptions.Value, mapRingColors, "distance ring");
		}

		public static void UpdateZoneOverlayColorSelection()
		{
			ParseColorOptions(ValConfig.ZoneOverlayColorOptions.Value, zoneOverlayColors, "zone overlay");
		}

		private static void ParseColorOptions(string optionsCsv, List<Color> target, string contextLabel)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			target.Clear();
			Color item = default(Color);
			Color item2 = default(Color);
			foreach (string item3 in optionsCsv.Split(new char[1] { ',' }).ToList())
			{
				if (item3.StartsWith("#"))
				{
					if (ColorUtility.TryParseHtmlString(item3.Trim(), ref item))
					{
						target.Add(item);
						continue;
					}
					Logger.LogWarning("Unable to parse color string " + item3 + " for " + contextLabel + " colors. It will be skipped");
				}
				else
				{
					string key = StringExtensions.CapitalizeFirstLetter(item3.Trim());
					if (defaultColors.TryGetValue(key, out var value) && ColorUtility.TryParseHtmlString(value, ref item2))
					{
						target.Add(item2);
					}
				}
			}
		}
	}
	internal static class Compatibility
	{
		public static bool IsDropThatEnabled = false;

		public static bool IsExpandWorldEnabled = false;

		public static bool IsFGNEnabled = false;

		public static bool IsCustomRaidsEnabled = false;

		public static bool IsJewelcraftingEnabled = false;

		public static bool IsVentureLocationResetEnabled = false;

		public static bool IsUpgradeWorldEnabled = false;

		public static bool IsValheimPlusEnabled = false;

		internal const string AugaGUID = "randyknapp.mods.auga";

		private const string DropThatGUID = "asharppen.valheim.drop_that";

		private const string DropThatSessionManagerTypeName = "DropThat.Drop.CharacterDropSystem.Managers.CharacterDropSessionManager";

		private static readonly Version DropThatCharacterDropTrackingFixed = new Version(3, 1, 6);

		private static Type DropThatCharacterDropSessionManager;

		private static MethodInfo DropThatCharacterModifyDrop;

		private static MethodInfo JewelcraftingBossHudPostfix;

		private const string ValheimPlusGUID = "org.bepinex.plugins.valheim_plus";

		private static Func<GameObject, int, int> ValheimPlusPickableYield;

		private static PropertyInfo ValheimPlusConfigCurrent;

		private static PropertyInfo ValheimPlusGameSection;

		private static PropertyInfo ValheimPlusGameEnabled;

		private static PropertyInfo ValheimPlusDamageScale;

		private static PropertyInfo ValheimPlusHealthScale;

		private static bool ValheimPlusPickableYieldFailed;

		private static bool ValheimPlusDifficultyFailed;

		public static bool CustomRaidsCompatActive
		{
			get
			{
				if (IsCustomRaidsEnabled)
				{
					return ValConfig.EnableCustomRaidsCompat.Value;
				}
				return false;
			}
		}

		public static bool IsAugaEnabled => Chainloader.PluginInfos.ContainsKey("randyknapp.mods.auga");

		public static bool DropThatCharacterModifyAvailable => DropThatCharacterModifyDrop != null;

		internal static void CheckModCompat()
		{
			try
			{
				Dictionary<string, BaseUnityPlugin> plugins = BepInExUtils.GetPlugins(false);
				if (plugins == null)
				{
					return;
				}
				if (plugins.TryGetValue("asharppen.valheim.drop_that", out var value))
				{
					IsDropThatEnabled = true;
					DropThatCharacterDropSessionManager = ((object)value)?.GetType().Assembly.GetType("DropThat.Drop.CharacterDropSystem.Managers.CharacterDropSessionManager");
					if (DropThatCharacterDropSessionManager != null)
					{
						DropThatCharacterModifyDrop = DropThatCharacterDropSessionManager.GetMethod("ModifyDrop", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
						{
							typeof(GameObject),
							typeof(List<KeyValuePair<GameObject, int>>),
							typeof(int)
						}, null);
					}
					if (!DropThatCharacterModifyAvailable)
					{
						Logger.LogWarning("Warning: DropThat compat method (CharacterDropSessionManager.ModifyDrop) not found; DropThat item modifiers will not be applied to creature loot.");
					}
					else
					{
						PluginInfo info = value.Info;
						object obj;
						if (info == null)
						{
							obj = null;
						}
						else
						{
							BepInPlugin metadata = info.Metadata;
							obj = ((metadata != null) ? metadata.Version : null);
						}
						Version version = (Version)obj;
						if (version != null && version < DropThatCharacterDropTrackingFixed)
						{
							Logger.LogWarning($"Drop That {version} detected; its creature drop modifiers need Drop That {DropThatCharacterDropTrackingFixed} or newer on this Valheim version and will not apply until it is updated.");
						}
						else
						{
							Logger.LogInfo("Drop That detected; its item modifiers will be applied to creature loot.");
						}
					}
				}
				if (Enumerable.Contains(plugins.Keys, "com.Fire.FiresGhettoNetworkMod"))
				{
					IsFGNEnabled = true;
				}
				if (Enumerable.Contains(plugins.Keys, "expand_world_size"))
				{
					IsExpandWorldEnabled = true;
				}
				if (Enumerable.Contains(plugins.Keys, "asharppen.valheim.custom_raids"))
				{
					IsCustomRaidsEnabled = true;
					Logger.LogInfo("Valheim.CustomRaids detected; CustomRaids raids will fire alongside SLS raids while EnableCustomRaidsCompat is enabled.");
				}
				if (Enumerable.Contains(plugins.Keys, "com.Venture.LocationReset"))
				{
					IsVentureLocationResetEnabled = true;
					LocationResetData.BlockedByModConflict = true;
					if (ValConfig.EnableLocationReset.Value)
					{
						Logger.LogWarning("VentureValheim LocationReset detected; SLS Location Reset has been disabled. Remove VentureValheim LocationReset to use SLS Location Reset - running both will fight over the same objects.");
					}
					else
					{
						Logger.LogInfo("VentureValheim LocationReset detected; SLS Location Reset is unavailable while it is installed.");
					}
				}
				if (Enumerable.Contains(plugins.Keys, "upgrade_world"))
				{
					IsUpgradeWorldEnabled = true;
					Logger.LogInfo("Upgrade World detected; its locations_reset / vegetation_reset commands overlap with SLS Location Reset. Avoid running both against the same zones.");
				}
				if (Enumerable.Contains(plugins.Keys, "org.bepinex.plugins.jewelcrafting"))
				{
					IsJewelcraftingEnabled = true;
					JewelcraftingBossHudPostfix = AccessTools.Method("Jewelcrafting.WorldBosses.BossHud+DisplayMultipleBossHuds:Postfix", (Type[])null, (Type[])null);
					if (JewelcraftingBossHudPostfix == null)
					{
						Logger.LogWarning("Jewelcrafting detected but DisplayMultipleBossHuds.Postfix could not be found; boss-HUD compatibility patch will be skipped.");
					}
				}
				if (plugins.TryGetValue("org.bepinex.plugins.valheim_plus", out var value2))
				{
					IsValheimPlusEnabled = true;
					BindValheimPlus(((object)value2).GetType().Assembly);
				}
			}
			catch
			{
				Logger.LogWarning("Unable to check mod compatibility. Ensure that Bepinex can load.");
			}
		}

		public static void DropThat_ModifyCharacterDrop(GameObject drop, List<KeyValuePair<GameObject, int>> drops, int index)
		{
			if (!DropThatCharacterModifyAvailable)
			{
				return;
			}
			try
			{
				DropThatCharacterModifyDrop.Invoke(null, new object[3] { drop, drops, index });
			}
			catch (Exception ex)
			{
				Logger.LogWarning("DropThat ModifyDrop failed: " + ex.Message);
			}
		}

		private static void BindValheimPlus(Assembly valheimPlus)
		{
			MethodInfo methodInfo = valheimPlus.GetType("ValheimPlus.GameClasses.PickableYieldState")?.GetMethod("CalculateYield", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(GameObject),
				typeof(int)
			}, null);
			if (methodInfo != null && methodInfo.ReturnType == typeof(int))
			{
				ValheimPlusPickableYield = (Func<GameObject, int, int>)Delegate.CreateDelegate(typeof(Func<GameObject, int, int>), methodInfo);
				Logger.LogInfo("Valheim Plus detected; its [Pickable] yields apply to pickables with an SLS loot table.");
			}
			else
			{
				Logger.LogWarning("Valheim Plus detected but its pickable yield (PickableYieldState.CalculateYield) was not found; its [Pickable] yields will not apply to pickables with an SLS loot table.");
			}
			Type type = valheimPlus.GetType("ValheimPlus.Configurations.Configuration");
			ValheimPlusGameSection = type?.GetProperty("Game", BindingFlags.Instance | BindingFlags.Public);
			Type obj = ValheimPlusGameSection?.PropertyType;
			ValheimPlusGameEnabled = obj?.GetProperty("IsEnabled", BindingFlags.Instance | BindingFlags.Public);
			ValheimPlusDamageScale = obj?.GetProperty("gameDifficultyDamageScale", BindingFlags.Instance | BindingFlags.Public);
			ValheimPlusHealthScale = obj?.GetProperty("gameDifficultyHealthScale", BindingFlags.Instance | BindingFlags.Public);
			if (ValheimPlusGameEnabled?.PropertyType == typeof(bool) && ValheimPlusDamageScale?.PropertyType == typeof(float) && ValheimPlusHealthScale?.PropertyType == typeof(float))
			{
				ValheimPlusConfigCurrent = type.GetProperty("Cur