Decompiled source of DyWorld Rising v0.1.0

DyWorldRising.dll

Decompiled 2 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DyWorldRising.Config;
using DyWorldRising.Data;
using DyWorldRising.Persistence;
using DyWorldRising.Systems;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.CastleBuilding;
using ProjectM.Network;
using ProjectM.Scripting;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("DyWorld Rising")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Heat-based faction aggression system for V Rising")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("DyWorldRising")]
[assembly: AssemblyTitle("DyWorldRising")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace DyWorldRising
{
	[BepInPlugin("com.dysoch.dyworldrising", "DyWorld Rising", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		private Harmony _harmony;

		private HeatDecayService _decayService;

		private SpawnOrchestrator _spawnOrchestrator;

		private SiegeOrchestrator _siegeOrchestrator;

		public static ManualLogSource Log { get; private set; }

		internal static HeatPersistenceService? Persistence { get; private set; }

		public override void Load()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] Loading ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DyWorld Rising");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.0");
			}
			log.LogInfo(val);
			DyWorldConfig.Init(((BasePlugin)this).Config);
			Persistence = new HeatPersistenceService(Paths.BepInExRootPath);
			Persistence.Load();
			_decayService = new HeatDecayService();
			_decayService.Start();
			_spawnOrchestrator = new SpawnOrchestrator();
			_spawnOrchestrator.Start();
			_siegeOrchestrator = new SiegeOrchestrator();
			_siegeOrchestrator.Start();
			_harmony = new Harmony("com.dysoch.dyworldrising");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			CommandRegistry.RegisterAll();
			Log.LogInfo((object)"[DyWorld Rising] Heat and Siege systems active.");
		}

		public override bool Unload()
		{
			Persistence?.Save();
			_decayService?.Dispose();
			_spawnOrchestrator?.Dispose();
			_siegeOrchestrator?.Dispose();
			CommandRegistry.UnregisterAssembly();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.dysoch.dyworldrising";

		public const string PLUGIN_NAME = "DyWorld Rising";

		public const string PLUGIN_VERSION = "0.1.0";
	}
}
namespace DyWorldRising.Systems
{
	public static class CastleSafetyChecker
	{
		private static int _diagCounter;

		public static bool IsInsideCastle(EntityManager em, Entity playerCharacter)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			bool flag2 = default(bool);
			try
			{
				if (!((EntityManager)(ref em)).Exists(playerCharacter))
				{
					return false;
				}
				if (!((EntityManager)(ref em)).HasComponent<LocalToWorld>(playerCharacter))
				{
					return false;
				}
				if (!((EntityManager)(ref em)).HasComponent<Team>(playerCharacter))
				{
					return false;
				}
				LocalToWorld componentData = ((EntityManager)(ref em)).GetComponentData<LocalToWorld>(playerCharacter);
				float3 position = ((LocalToWorld)(ref componentData)).Position;
				int value = ((EntityManager)(ref em)).GetComponentData<Team>(playerCharacter).Value;
				EntityQuery val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<CastleTerritory>() });
				NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				int length = val2.Length;
				int num = 0;
				bool flag = false;
				try
				{
					Enumerator<Entity> enumerator = val2.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						if (((EntityManager)(ref em)).HasComponent<Team>(current) && ((EntityManager)(ref em)).GetComponentData<Team>(current).Value == value)
						{
							num++;
							if (PositionInsideTerritory(em, current, position))
							{
								flag = true;
								break;
							}
						}
					}
				}
				finally
				{
					val2.Dispose();
					((EntityQuery)(ref val)).Dispose();
				}
				if (++_diagCounter >= 300)
				{
					_diagCounter = 0;
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(87, 6, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[DyWorld Rising] CastleCheck: territories=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(length);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", owned=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("playerTeam=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(value);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", pos=(");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(position.x, "F0");
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(position.z, "F0");
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("), insideCastle=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<bool>(flag);
					}
					log.LogInfo(val3);
				}
				return flag;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[DyWorld Rising] CastleSafetyChecker: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val4);
			}
			return false;
		}

		private static bool PositionInsideTerritory(EntityManager em, Entity territory, float3 pos)
		{
			//IL_0002: 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)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((EntityManager)(ref em)).HasComponent<LocalToWorld>(territory))
			{
				return false;
			}
			LocalToWorld componentData = ((EntityManager)(ref em)).GetComponentData<LocalToWorld>(territory);
			float3 position = ((LocalToWorld)(ref componentData)).Position;
			float value = DyWorldConfig.SafeCastleRadius.Value;
			float num = pos.x - position.x;
			float num2 = pos.z - position.z;
			return num * num + num2 * num2 < value * value;
		}
	}
	public static class DayNightHelper
	{
		private const float DayDurationSeconds = 3600f;

		private const int DayStartHour = 9;

		private const int DayEndHour = 17;

		public static float GetNormalisedTime(World? _ = null)
		{
			return (float)(DateTimeOffset.UtcNow.TimeOfDay.TotalSeconds % 3600.0 / 3600.0);
		}

		public static bool IsNight(World? _ = null)
		{
			float normalisedTime = GetNormalisedTime();
			float num = 0.375f;
			float num2 = 17f / 24f;
			if (!(normalisedTime < num))
			{
				return normalisedTime >= num2;
			}
			return true;
		}

		public static bool IsDawnOrDusk(World? _ = null)
		{
			float normalisedTime = GetNormalisedTime();
			float num = 0.375f;
			float num2 = 17f / 24f;
			float num3 = 1f / 48f;
			if (!(normalisedTime > num - num3) || !(normalisedTime < num + num3))
			{
				if (normalisedTime > num2 - num3)
				{
					return normalisedTime < num2 + num3;
				}
				return false;
			}
			return true;
		}
	}
	public readonly struct AllianceEntry
	{
		public readonly VRisingFaction Ally;

		public readonly float HeatShare;

		public AllianceEntry(VRisingFaction ally, float share)
		{
			Ally = ally;
			HeatShare = share;
		}
	}
	public static class FactionAlliances
	{
		private static readonly Dictionary<VRisingFaction, AllianceEntry[]> _alliances = new Dictionary<VRisingFaction, AllianceEntry[]>
		{
			[VRisingFaction.Militia] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.ChurchOfLuminance, 0.2f)
			},
			[VRisingFaction.ChurchOfLuminance] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.Militia, 0.2f)
			},
			[VRisingFaction.Bandits] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.Blackfang, 0.15f)
			},
			[VRisingFaction.Blackfang] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.Bandits, 0.15f)
			},
			[VRisingFaction.Undead] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.Cursed, 0.1f)
			},
			[VRisingFaction.Cursed] = new AllianceEntry[2]
			{
				new AllianceEntry(VRisingFaction.Undead, 0.1f),
				new AllianceEntry(VRisingFaction.Werewolves, 0.1f)
			},
			[VRisingFaction.Werewolves] = new AllianceEntry[1]
			{
				new AllianceEntry(VRisingFaction.Cursed, 0.1f)
			}
		};

		public static bool TryGetAllies(VRisingFaction faction, out AllianceEntry[] allies)
		{
			return _alliances.TryGetValue(faction, out allies);
		}
	}
	public enum VRisingFaction
	{
		Unknown,
		Militia,
		ChurchOfLuminance,
		Bandits,
		Werewolves,
		Undead,
		Gloomrot,
		DunleyFarmers,
		Legion,
		Creature,
		Blackfang,
		Cursed
	}
	public class FactionData
	{
		public string DisplayName { get; init; } = string.Empty;


		public NamedPrefab[] PatrolUnits { get; init; } = Array.Empty<NamedPrefab>();


		public TieredVBlood[] VBloods { get; init; } = Array.Empty<TieredVBlood>();

	}
	public readonly struct NamedPrefab
	{
		public readonly string Name;

		public readonly PrefabGUID Guid;

		public readonly int Level;

		public NamedPrefab(string name, int hash, int level = 0)
		{
			//IL_0009: 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)
			Name = name;
			Guid = new PrefabGUID(hash);
			Level = level;
		}
	}
	public static class FactionDatabase
	{
		private static readonly Dictionary<string, PrefabGUID> _resolvedByName = new Dictionary<string, PrefabGUID>();

		private static readonly Dictionary<VRisingFaction, FactionData> _data = new Dictionary<VRisingFaction, FactionData>
		{
			[VRisingFaction.Militia] = new FactionData
			{
				DisplayName = "Militia",
				PatrolUnits = new NamedPrefab[11]
				{
					new NamedPrefab("CHAR_Militia_Guard", 1730498275, 28),
					new NamedPrefab("CHAR_Militia_Longbowman", 203103783, 32),
					new NamedPrefab("CHAR_Militia_Crossbow", 956965183, 30),
					new NamedPrefab("CHAR_Militia_Heavy", 2005508157, 36),
					new NamedPrefab("CHAR_Militia_Light", -63435588, 22),
					new NamedPrefab("CHAR_Militia_Bomber", 847893333, 26),
					new NamedPrefab("CHAR_Militia_Horseman", -235172198, 34),
					new NamedPrefab("CHAR_Militia_Devoted", 1660801216, 30),
					new NamedPrefab("CHAR_Militia_Hound", -249647316, 24),
					new NamedPrefab("CHAR_Militia_Rider", -1719333743, 34),
					new NamedPrefab("CHAR_Militia_Miner_Standard", -1072754152, 20)
				},
				VBloods = new TieredVBlood[7]
				{
					new TieredVBlood("Vincent the Frostbringer", "CHAR_Militia_Guard_VBlood", -29797003, 40),
					new TieredVBlood("Christina the Sun Priestess", "CHAR_Militia_Nun_VBlood", -99012450, 44),
					new TieredVBlood("Tristan the Vampire Hunter", "CHAR_VHunter_Leader_VBlood", -1449631170, 46),
					new TieredVBlood("The Bishop of Dunley", "CHAR_Militia_BishopOfDunley_VBlood", -680831417, 52),
					new TieredVBlood("Fabian the Knight Captain", "CHAR_Militia_Fabian_VBlood", 619948378, 48),
					new TieredVBlood("The Hound Master", "CHAR_Militia_HoundMaster_VBlood", -784265984, 42),
					new TieredVBlood("Octavian the Militia Captain", "CHAR_Militia_Leader_VBlood", 1688478381, 58)
				}
			},
			[VRisingFaction.Bandits] = new FactionData
			{
				DisplayName = "Bandits",
				PatrolUnits = new NamedPrefab[10]
				{
					new NamedPrefab("CHAR_Bandit_Thug", -301730941, 12),
					new NamedPrefab("CHAR_Bandit_Stalker", -309264723, 18),
					new NamedPrefab("CHAR_Bandit_Trapper", -589412777, 16),
					new NamedPrefab("CHAR_Bandit_Hunter", -1301144178, 20),
					new NamedPrefab("CHAR_Bandit_Bomber", -1128238456, 22),
					new NamedPrefab("CHAR_Bandit_Deadeye", -1030822544, 20),
					new NamedPrefab("CHAR_Bandit_Scout", 1220569089, 14),
					new NamedPrefab("CHAR_Bandit_Rascal", -1194643220, 10),
					new NamedPrefab("CHAR_Bandit_Thief", 923140362, 14),
					new NamedPrefab("CHAR_Bandit_Mugger", 2057508774, 12)
				},
				VBloods = new TieredVBlood[6]
				{
					new TieredVBlood("Rufus the Foreman", "CHAR_Bandit_Foreman_VBlood", 2122229952, 16),
					new TieredVBlood("Keely the Frost Archer", "CHAR_Bandit_Frostarrow_VBlood", 1124739990, 20),
					new TieredVBlood("Errol the Stonebreaker", "CHAR_Bandit_StoneBreaker_VBlood", -2025101517, 20),
					new TieredVBlood("Lidia the Chaos Archer", "CHAR_Bandit_Chaosarrow_VBlood", 763273073, 26),
					new TieredVBlood("Clive the Firestarter", "CHAR_Bandit_Bomber_VBlood", 1896428751, 30),
					new TieredVBlood("Quincey the Bandit King", "CHAR_Bandit_Tourok_VBlood", -1659822956, 37)
				}
			},
			[VRisingFaction.ChurchOfLuminance] = new FactionData
			{
				DisplayName = "Church of Luminance",
				PatrolUnits = new NamedPrefab[11]
				{
					new NamedPrefab("CHAR_ChurchOfLight_Archer", 426583055, 36),
					new NamedPrefab("CHAR_ChurchOfLight_Paladin", 1728773109, 46),
					new NamedPrefab("CHAR_ChurchOfLight_Cleric", -1464869978, 40),
					new NamedPrefab("CHAR_ChurchOfLight_Lightweaver", 1185952775, 44),
					new NamedPrefab("CHAR_ChurchOfLight_Priest", 1406393857, 38),
					new NamedPrefab("CHAR_ChurchOfLight_Footman", 2128996433, 32),
					new NamedPrefab("CHAR_ChurchOfLight_Knight_2H", -930333806, 50),
					new NamedPrefab("CHAR_ChurchOfLight_Knight_Shield", 794228023, 48),
					new NamedPrefab("CHAR_ChurchOfLight_Rifleman", 1148936156, 42),
					new NamedPrefab("CHAR_ChurchOfLight_SlaveMaster_Enforcer", 891705701, 52),
					new NamedPrefab("CHAR_ChurchOfLight_SlaveRuffian", -1875351031, 36)
				},
				VBloods = new TieredVBlood[4]
				{
					new TieredVBlood("Magnus the Overseer", "CHAR_ChurchOfLight_Overseer_VBlood", -26105228, 41),
					new TieredVBlood("Azariel the Sunbringer", "CHAR_ChurchOfLight_Cardinal_VBlood", 114912615, 68),
					new TieredVBlood("Solarus the Immaculate", "CHAR_ChurchOfLight_Paladin_VBlood", -740796338, 82),
					new TieredVBlood("The Sommelier", "CHAR_ChurchOfLight_Sommelier_VBlood", 192051202, 60)
				}
			},
			[VRisingFaction.Undead] = new FactionData
			{
				DisplayName = "Undead",
				PatrolUnits = new NamedPrefab[13]
				{
					new NamedPrefab("CHAR_Undead_Necromancer", -572568236, 36),
					new NamedPrefab("CHAR_Undead_Assassin", -1365627158, 28),
					new NamedPrefab("CHAR_Undead_Priest", -1653554504, 32),
					new NamedPrefab("CHAR_Undead_RottingGhoul", -1722506709, 20),
					new NamedPrefab("CHAR_Undead_SkeletonSoldier_Armored_Farbane", -837329073, 22),
					new NamedPrefab("CHAR_Undead_SkeletonSoldier_Armored_Dunley", 952695804, 38),
					new NamedPrefab("CHAR_Undead_SkeletonMage", -1287507270, 34),
					new NamedPrefab("CHAR_Undead_SkeletonApprentice", -1789347076, 18),
					new NamedPrefab("CHAR_Undead_Guardian", -1967480038, 40),
					new NamedPrefab("CHAR_Undead_ShadowSoldier", 678628353, 36),
					new NamedPrefab("CHAR_Undead_UndyingGhoul", 1640311129, 26),
					new NamedPrefab("CHAR_Undead_GhostBanshee", -1146194149, 30),
					new NamedPrefab("CHAR_Undead_GhostAssassin", 849891426, 32)
				},
				VBloods = new TieredVBlood[8]
				{
					new TieredVBlood("Nicholaus the Fallen", "CHAR_Undead_Priest_VBlood", 153390636, 37),
					new TieredVBlood("The Bishop of Death", "CHAR_Undead_BishopOfDeath_VBlood", 577478542, 48),
					new TieredVBlood("Foulrot the Soultaker", "CHAR_Undead_ZealousCultist_VBlood", -1208888966, 62),
					new TieredVBlood("The Bishop of Shadows", "CHAR_Undead_BishopOfShadows_VBlood", 939467639, 66),
					new TieredVBlood("The Undead Infiltrator", "CHAR_Undead_Infiltrator_VBlood", 613251918, 50),
					new TieredVBlood("The Undead Leader", "CHAR_Undead_Leader_Vblood", -1365931036, 55),
					new TieredVBlood("The Cursed Smith", "CHAR_Undead_CursedSmith_VBlood", 326378955, 44),
					new TieredVBlood("The Arena Champion", "CHAR_Undead_ArenaChampion_VBlood", -753453016, 70)
				}
			},
			[VRisingFaction.Werewolves] = new FactionData
			{
				DisplayName = "Werewolves",
				PatrolUnits = new NamedPrefab[2]
				{
					new NamedPrefab("CHAR_Farmlands_HostileVillager_Werewolf", -951976780, 36),
					new NamedPrefab("CHAR_WerewolfChieftain_Human", -1505705712, 56)
				},
				VBloods = new TieredVBlood[1]
				{
					new TieredVBlood("Willfred the Werewolf Chief", "CHAR_WerewolfChieftain_VBlood_GateBoss_Major", 2079933370, 64)
				}
			},
			[VRisingFaction.Gloomrot] = new FactionData
			{
				DisplayName = "Gloomrot",
				PatrolUnits = new NamedPrefab[9]
				{
					new NamedPrefab("CHAR_Gloomrot_Technician", 820492683, 55),
					new NamedPrefab("CHAR_Gloomrot_Railgunner", 1732477970, 60),
					new NamedPrefab("CHAR_Gloomrot_TractorBeamer", -293507834, 58),
					new NamedPrefab("CHAR_Gloomrot_Tazer", 674807351, 56),
					new NamedPrefab("CHAR_Gloomrot_Pyro", -322293503, 52),
					new NamedPrefab("CHAR_Gloomrot_SentryOfficer", 1401026468, 62),
					new NamedPrefab("CHAR_Gloomrot_AceIncinerator", 1756241788, 64),
					new NamedPrefab("CHAR_Gloomrot_Batoon", -1707267769, 54),
					new NamedPrefab("CHAR_Gloomrot_Technician_Labworker", -825299465, 50)
				},
				VBloods = new TieredVBlood[8]
				{
					new TieredVBlood("The Gloomrot Purifier", "CHAR_Gloomrot_Purifier_VBlood", 106480588, 58),
					new TieredVBlood("Iva the Rampant", "CHAR_Gloomrot_Iva_VBlood", 172235178, 60),
					new TieredVBlood("Jade the Vampire Hunter", "CHAR_VHunter_Jade_VBlood", -1968372384, 62),
					new TieredVBlood("The Professor", "CHAR_Gloomrot_TheProfessor_VBlood", 814083983, 65),
					new TieredVBlood("The Gloomrot Monster", "CHAR_Gloomrot_Monster_VBlood", 1233988687, 68),
					new TieredVBlood("Voltatia the Power Master", "CHAR_Gloomrot_Voltage_VBlood", -1101874342, 77),
					new TieredVBlood("The Railgun Sergeant", "CHAR_Gloomrot_RailgunSergeant_VBlood", 2054432370, 64),
					new TieredVBlood("The Archmage", "CHAR_ArchMage_VBlood", -2013903325, 70)
				}
			},
			[VRisingFaction.DunleyFarmers] = new FactionData
			{
				DisplayName = "Dunley Farmers",
				PatrolUnits = new NamedPrefab[8]
				{
					new NamedPrefab("CHAR_Farmlands_Villager_Male", 1887807944, 26),
					new NamedPrefab("CHAR_Farmlands_Villager_Female", 525027204, 26),
					new NamedPrefab("CHAR_Farmlands_Farmer", -1342764880, 24),
					new NamedPrefab("CHAR_Farmlands_Woodcutter_Standard", -893091615, 28),
					new NamedPrefab("CHAR_Farmlands_HostileVillager_Male_Club", -164116132, 22),
					new NamedPrefab("CHAR_Farmlands_HostileVillager_Male_Shovel", -864975423, 22),
					new NamedPrefab("CHAR_Farmlands_HostileVillager_Female_Pitchfork", 1576267559, 22),
					new NamedPrefab("CHAR_Farmlands_HostileVillager_Female_FryingPan", 729746981, 22)
				},
				VBloods = new TieredVBlood[2]
				{
					new TieredVBlood("Beatrice the Tailor", "CHAR_Villager_Tailor_VBlood", -1942352521, 38),
					new TieredVBlood("The Cursed Wanderer", "CHAR_Villager_CursedWanderer_VBlood", 109969450, 42)
				}
			},
			[VRisingFaction.Legion] = new FactionData
			{
				DisplayName = "Legion",
				PatrolUnits = new NamedPrefab[8]
				{
					new NamedPrefab("CHAR_Legion_NightMaiden", -494298686, 62),
					new NamedPrefab("CHAR_Legion_Assassin", -1076780215, 64),
					new NamedPrefab("CHAR_Legion_Shadowkin", 1980594081, 60),
					new NamedPrefab("CHAR_Legion_Nightmare", -1009917656, 68),
					new NamedPrefab("CHAR_Legion_Vargulf", -653348998, 66),
					new NamedPrefab("CHAR_Legion_BloodProphet", 1912966420, 58),
					new NamedPrefab("CHAR_Legion_Dreadhorn", 981369753, 64),
					new NamedPrefab("CHAR_Legion_Gargoyle", -65981941, 60)
				},
				VBloods = new TieredVBlood[5]
				{
					new TieredVBlood("The Blood Knight", "CHAR_Vampire_BloodKnight_VBlood", 495971434, 60),
					new TieredVBlood("The Ice Ranger", "CHAR_Vampire_IceRanger_VBlood", 795262842, 66),
					new TieredVBlood("The Bat Vampire", "CHAR_BatVampire_VBlood", 1112948824, 68),
					new TieredVBlood("The High Lord", "CHAR_Vampire_HighLord_VBlood", -496360395, 78),
					new TieredVBlood("Dracula", "CHAR_Vampire_Dracula_VBlood", -327335305, 90)
				}
			},
			[VRisingFaction.Creature] = new FactionData
			{
				DisplayName = "Creatures",
				PatrolUnits = new NamedPrefab[18]
				{
					new NamedPrefab("CHAR_Forest_Wolf", -1418430647, 8),
					new NamedPrefab("CHAR_Forest_Bear_Standard", 1043643344, 26),
					new NamedPrefab("CHAR_Forest_Deer", 1897056612, 4),
					new NamedPrefab("CHAR_Forest_Moose", -831097925, 22),
					new NamedPrefab("CHAR_Forest_AngryMoose", 2097040330, 28),
					new NamedPrefab("CHAR_Spider_Melee", 2136899683, 14),
					new NamedPrefab("CHAR_Spider_Range", 2103131615, 16),
					new NamedPrefab("CHAR_Spider_Forest", -581295882, 18),
					new NamedPrefab("CHAR_Spider_Forestling", 574276383, 12),
					new NamedPrefab("CHAR_Spider_Broodmother", 342127250, 22),
					new NamedPrefab("CHAR_Winter_Wolf", 134039094, 18),
					new NamedPrefab("CHAR_Winter_Bear_Standard", 2041915372, 30),
					new NamedPrefab("CHAR_Winter_Moose", -779632831, 26),
					new NamedPrefab("CHAR_Harpy_Scratcher", 1462269123, 40),
					new NamedPrefab("CHAR_Harpy_Dasher", -1846851895, 42),
					new NamedPrefab("CHAR_Harpy_Sorceress", 1224283123, 44),
					new NamedPrefab("CHAR_Mutant_Wolf", 572729167, 48),
					new NamedPrefab("CHAR_Mutant_Bear_Standard", 1938756250, 52)
				},
				VBloods = new TieredVBlood[10]
				{
					new TieredVBlood("Alpha Wolf", "CHAR_Forest_Wolf_VBlood", -1905691330, 16),
					new TieredVBlood("Ungora the Spider Queen", "CHAR_Spider_Queen_VBlood", -548489519, 27),
					new TieredVBlood("Putrid Rat", "CHAR_Vermin_DireRat_VBlood", -2039908510, 30),
					new TieredVBlood("Polora the Feywalker", "CHAR_Poloma_VBlood", -484556888, 34),
					new TieredVBlood("Ferocious Bear", "CHAR_Forest_Bear_Dire_Vblood", -1391546313, 36),
					new TieredVBlood("The Harpy Matriarch", "CHAR_Harpy_Matriarch_VBlood", 685266977, 54),
					new TieredVBlood("The Manticore", "CHAR_Manticore_VBlood", -393555055, 68),
					new TieredVBlood("The Wendigo", "CHAR_Wendigo_VBlood", 24378719, 70),
					new TieredVBlood("The Winter Yeti", "CHAR_Winter_Yeti_VBlood", -1347412392, 60),
					new TieredVBlood("The Geomancer", "CHAR_Geomancer_Human_VBlood", -1065970933, 55)
				}
			},
			[VRisingFaction.Blackfang] = new FactionData
			{
				DisplayName = "Blackfang",
				PatrolUnits = new NamedPrefab[9]
				{
					new NamedPrefab("CHAR_Blackfang_Peon", -1562098554, 14),
					new NamedPrefab("CHAR_Blackfang_Striker", 761646020, 18),
					new NamedPrefab("CHAR_Blackfang_Sentinel", 1531777139, 22),
					new NamedPrefab("CHAR_Blackfang_DartFlinger", 1209580976, 20),
					new NamedPrefab("CHAR_Blackfang_Lurker", -1733829912, 20),
					new NamedPrefab("CHAR_Blackfang_Viper", -436956599, 24),
					new NamedPrefab("CHAR_Blackfang_Venomblade", 1864177126, 26),
					new NamedPrefab("CHAR_Blackfang_Alchemist", 326501064, 22),
					new NamedPrefab("CHAR_Blackfang_WoodCarver", -1508046438, 18)
				},
				VBloods = new TieredVBlood[5]
				{
					new TieredVBlood("Valyr the Cunning", "CHAR_Blackfang_Valyr_VBlood", 173259239, 26),
					new TieredVBlood("Lucie the Scourge", "CHAR_Blackfang_Lucie_VBlood", 1295855316, 28),
					new TieredVBlood("Livith the Mad", "CHAR_Blackfang_Livith_VBlood", -1383529374, 32),
					new TieredVBlood("Morgana the Witch Queen", "CHAR_Blackfang_Morgana_VBlood", 591725925, 40),
					new TieredVBlood("The Carver Boss", "CHAR_Blackfang_CarverBoss_VBlood", -1669199769, 36)
				}
			},
			[VRisingFaction.Cursed] = new FactionData
			{
				DisplayName = "Cursed",
				PatrolUnits = new NamedPrefab[9]
				{
					new NamedPrefab("CHAR_Cursed_Wolf", -218175217, 38),
					new NamedPrefab("CHAR_Cursed_Bear_Standard", -559819989, 44),
					new NamedPrefab("CHAR_Cursed_Witch", -56441915, 40),
					new NamedPrefab("CHAR_Cursed_MonsterToad", 575918722, 44),
					new NamedPrefab("CHAR_Cursed_ToadSpitter", 1478790879, 38),
					new NamedPrefab("CHAR_Cursed_Nightlurker", -2046268156, 40),
					new NamedPrefab("CHAR_Cursed_Mosquito", -744966291, 36),
					new NamedPrefab("CHAR_Corrupted_Wolf", 616274140, 50),
					new NamedPrefab("CHAR_Corrupted_Bear_Standard", -1697944553, 52)
				},
				VBloods = new TieredVBlood[3]
				{
					new TieredVBlood("The Cursed Witch", "CHAR_Cursed_Witch_VBlood", -910296704, 40),
					new TieredVBlood("The Toad King", "CHAR_Cursed_ToadKing_VBlood", -203043163, 44),
					new TieredVBlood("The Cursed Mountain Beast", "CHAR_Cursed_MountainBeast_VBlood", -1936575244, 56)
				}
			}
		};

		private static Dictionary<int, (VRisingFaction Faction, string Name, int Level)> _prefabIndex = BuildPrefabIndex();

		public static int ResolvedCount => _resolvedByName.Count;

		public static IEnumerable<VRisingFaction> AllFactions => _data.Keys;

		public static void AutoResolve(PrefabCollectionSystem prefabSystem)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			_resolvedByName.Clear();
			Dictionary<string, PrefabGUID> dictionary = new Dictionary<string, PrefabGUID>(StringComparer.Ordinal);
			Enumerator<string, PrefabGUID> enumerator = prefabSystem.SpawnableNameToPrefabGuidDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, PrefabGUID> current = enumerator.Current;
				dictionary[current.Key] = current.Value;
			}
			if (dictionary.Count == 0)
			{
				Plugin.Log.LogWarning((object)"[DyWorld Rising] AutoResolve: SpawnableNameToPrefabGuidDictionary is empty — running too early? Will retry next frame.");
				return;
			}
			int resolved = 0;
			int mismatch = 0;
			int failed = 0;
			foreach (KeyValuePair<VRisingFaction, FactionData> datum in _data)
			{
				datum.Deconstruct(out var _, out var value);
				FactionData factionData = value;
				NamedPrefab[] patrolUnits = factionData.PatrolUnits;
				PrefabGUID guid;
				for (int i = 0; i < patrolUnits.Length; i++)
				{
					NamedPrefab namedPrefab = patrolUnits[i];
					string name = namedPrefab.Name;
					guid = namedPrefab.Guid;
					Resolve(dictionary, name, ((PrefabGUID)(ref guid)).GuidHash, ref resolved, ref mismatch, ref failed);
				}
				TieredVBlood[] vBloods = factionData.VBloods;
				for (int i = 0; i < vBloods.Length; i++)
				{
					TieredVBlood tieredVBlood = vBloods[i];
					string name2 = (string.IsNullOrEmpty(tieredVBlood.PrefabName) ? tieredVBlood.DisplayName : tieredVBlood.PrefabName);
					guid = tieredVBlood.Guid;
					Resolve(dictionary, name2, ((PrefabGUID)(ref guid)).GuidHash, ref resolved, ref mismatch, ref failed);
				}
			}
			RebuildPrefabIndex();
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] AutoResolve complete: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(resolved);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ok, ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(mismatch);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" hash mismatches logged, ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(failed);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found.");
			}
			log.LogInfo(val);
		}

		private static void Resolve(Dictionary<string, PrefabGUID> managed, string name, int fallbackHash, ref int resolved, ref int mismatch, ref int failed)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			PrefabGUID value;
			if (string.IsNullOrEmpty(name))
			{
				failed++;
			}
			else if (managed.TryGetValue(name, out value))
			{
				_resolvedByName[name] = value;
				if (((PrefabGUID)(ref value)).GuidHash != fallbackHash)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] Hash mismatch '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': hardcoded=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(fallbackHash);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" actual=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((PrefabGUID)(ref value)).GuidHash);
					}
					log.LogWarning(val);
					mismatch++;
				}
				resolved++;
			}
			else
			{
				failed++;
			}
		}

		private static void RebuildPrefabIndex()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, (VRisingFaction, string, int)> dictionary = new Dictionary<int, (VRisingFaction, string, int)>();
			foreach (KeyValuePair<VRisingFaction, FactionData> datum in _data)
			{
				datum.Deconstruct(out var key, out var value);
				VRisingFaction item = key;
				FactionData factionData = value;
				NamedPrefab[] patrolUnits = factionData.PatrolUnits;
				for (int i = 0; i < patrolUnits.Length; i++)
				{
					NamedPrefab namedPrefab = patrolUnits[i];
					PrefabGUID resolvedGuid = GetResolvedGuid(namedPrefab.Name, namedPrefab.Guid);
					dictionary[((PrefabGUID)(ref resolvedGuid)).GuidHash] = (item, namedPrefab.Name, namedPrefab.Level);
				}
				TieredVBlood[] vBloods = factionData.VBloods;
				for (int i = 0; i < vBloods.Length; i++)
				{
					TieredVBlood tieredVBlood = vBloods[i];
					PrefabGUID resolvedGuid2 = GetResolvedGuid(string.IsNullOrEmpty(tieredVBlood.PrefabName) ? tieredVBlood.DisplayName : tieredVBlood.PrefabName, tieredVBlood.Guid);
					dictionary[((PrefabGUID)(ref resolvedGuid2)).GuidHash] = (item, tieredVBlood.DisplayName, tieredVBlood.Level);
				}
			}
			_prefabIndex = dictionary;
		}

		public static PrefabGUID GetResolvedGuid(string name, PrefabGUID fallback)
		{
			//IL_0011: 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)
			if (!_resolvedByName.TryGetValue(name, out var value))
			{
				return fallback;
			}
			return value;
		}

		public static PrefabGUID GetResolvedGuid(NamedPrefab unit)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return GetResolvedGuid(unit.Name, unit.Guid);
		}

		public static PrefabGUID GetResolvedGuid(TieredVBlood vb)
		{
			//IL_001c: 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)
			return GetResolvedGuid(string.IsNullOrEmpty(vb.PrefabName) ? vb.DisplayName : vb.PrefabName, vb.Guid);
		}

		public static int DumpSpawnables(PrefabCollectionSystem prefabSystem, string filter, string outputPath)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, PrefabGUID> spawnableNameToPrefabGuidDictionary = prefabSystem.SpawnableNameToPrefabGuidDictionary;
			List<string> list = new List<string>();
			string text = filter.ToUpperInvariant();
			Enumerator<string, PrefabGUID> enumerator = spawnableNameToPrefabGuidDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, PrefabGUID> current = enumerator.Current;
				if (text.Length == 0 || current.Key.ToUpperInvariant().Contains(text))
				{
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 2);
					PrefabGUID value = current.Value;
					defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref value)).GuidHash, 12);
					defaultInterpolatedStringHandler.AppendLiteral("  ");
					defaultInterpolatedStringHandler.AppendFormatted(current.Key);
					list.Add(defaultInterpolatedStringHandler.ToStringAndClear());
				}
			}
			list.Sort(StringComparer.OrdinalIgnoreCase);
			File.WriteAllLines(outputPath, list);
			return list.Count;
		}

		public static bool TryGetFaction(PrefabGUID prefab, out VRisingFaction faction)
		{
			if (_prefabIndex.TryGetValue(((PrefabGUID)(ref prefab)).GuidHash, out (VRisingFaction, string, int) value))
			{
				(faction, _, _) = value;
				return true;
			}
			faction = VRisingFaction.Unknown;
			return false;
		}

		public static int GetUnitLevel(PrefabGUID prefab)
		{
			if (!_prefabIndex.TryGetValue(((PrefabGUID)(ref prefab)).GuidHash, out (VRisingFaction, string, int) value))
			{
				return 0;
			}
			return value.Item3;
		}

		public static bool TryGetData(VRisingFaction faction, out FactionData data)
		{
			return _data.TryGetValue(faction, out data);
		}

		public static void ValidateAllPrefabs(PrefabCollectionSystem _)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			int count = 0;
			foreach (KeyValuePair<VRisingFaction, FactionData> datum in _data)
			{
				datum.Deconstruct(out var key, out var value);
				VRisingFaction value2 = key;
				FactionData factionData = value;
				NamedPrefab[] patrolUnits = factionData.PatrolUnits;
				PrefabGUID guid2;
				for (int i = 0; i < patrolUnits.Length; i++)
				{
					NamedPrefab namedPrefab = patrolUnits[i];
					if (!_resolvedByName.ContainsKey(namedPrefab.Name))
					{
						string label = $"{value2}/{namedPrefab.Name}";
						guid2 = namedPrefab.Guid;
						Warn(ref count, label, ((PrefabGUID)(ref guid2)).GuidHash, "not in spawnable dict");
					}
				}
				TieredVBlood[] vBloods = factionData.VBloods;
				for (int i = 0; i < vBloods.Length; i++)
				{
					TieredVBlood tieredVBlood = vBloods[i];
					string key2 = (string.IsNullOrEmpty(tieredVBlood.PrefabName) ? tieredVBlood.DisplayName : tieredVBlood.PrefabName);
					if (!_resolvedByName.ContainsKey(key2))
					{
						string label2 = $"{value2}/{tieredVBlood.DisplayName}";
						guid2 = tieredVBlood.Guid;
						Warn(ref count, label2, ((PrefabGUID)(ref guid2)).GuidHash, "not in spawnable dict");
					}
				}
			}
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val;
			foreach (VRisingRegion allRegion in RegionDatabase.AllRegions)
			{
				if (!RegionDatabase.TryGetData(allRegion, out RegionData data))
				{
					continue;
				}
				PrefabGUID[] guardianUnits = data.GuardianUnits;
				for (int i = 0; i < guardianUnits.Length; i++)
				{
					PrefabGUID guid = guardianUnits[i];
					if (!_resolvedByName.Values.Any((PrefabGUID v) => ((PrefabGUID)(ref v)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash))
					{
						ManualLogSource log = Plugin.Log;
						val = new BepInExWarningLogInterpolatedStringHandler(81, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising][WARN] Region guardian ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((PrefabGUID)(ref guid)).GuidHash);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<VRisingRegion>(allRegion);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — hash not confirmed by spawnable dict");
						}
						log.LogWarning(val);
					}
				}
			}
			if (count == 0)
			{
				Plugin.Log.LogInfo((object)"[DyWorld Rising] All faction/VBlood names confirmed in spawnable dict.");
				return;
			}
			ManualLogSource log2 = Plugin.Log;
			val = new BepInExWarningLogInterpolatedStringHandler(128, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" entry/ies not found in spawnable dict — will use hardcoded hash fallback for kill tracking; spawning may fail.");
			}
			log2.LogWarning(val);
		}

		private static void Warn(ref int count, string label, int hash, string file)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising][WARN] Invalid PrefabGUID ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(hash);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — update ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(file);
			}
			log.LogWarning(val);
			count++;
		}

		private static Dictionary<int, (VRisingFaction, string, int)> BuildPrefabIndex()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, (VRisingFaction, string, int)> dictionary = new Dictionary<int, (VRisingFaction, string, int)>();
			foreach (KeyValuePair<VRisingFaction, FactionData> datum in _data)
			{
				datum.Deconstruct(out var key, out var value);
				VRisingFaction item = key;
				FactionData factionData = value;
				NamedPrefab[] patrolUnits = factionData.PatrolUnits;
				PrefabGUID guid;
				for (int i = 0; i < patrolUnits.Length; i++)
				{
					NamedPrefab namedPrefab = patrolUnits[i];
					guid = namedPrefab.Guid;
					dictionary[((PrefabGUID)(ref guid)).GuidHash] = (item, namedPrefab.Name, namedPrefab.Level);
				}
				TieredVBlood[] vBloods = factionData.VBloods;
				for (int i = 0; i < vBloods.Length; i++)
				{
					TieredVBlood tieredVBlood = vBloods[i];
					guid = tieredVBlood.Guid;
					dictionary[((PrefabGUID)(ref guid)).GuidHash] = (item, tieredVBlood.DisplayName, tieredVBlood.Level);
				}
			}
			return dictionary;
		}
	}
	public static class GearLevelHelper
	{
		public static int GetPlayerGearLevel(EntityManager em, Entity characterEntity)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((EntityManager)(ref em)).Exists(characterEntity))
				{
					return 0;
				}
				if (!((EntityManager)(ref em)).HasComponent<Equipment>(characterEntity))
				{
					return 0;
				}
				Equipment componentData = ((EntityManager)(ref em)).GetComponentData<Equipment>(characterEntity);
				return (int)((Equipment)(ref componentData)).GetFullLevel();
			}
			catch
			{
				return 0;
			}
		}

		public static int GetUnitLevel(PrefabGUID prefabGuid)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return FactionDatabase.GetUnitLevel(prefabGuid);
		}

		public static float ComputeHeatMultiplier(int playerGearLevel, int unitGearLevel)
		{
			if (playerGearLevel <= 0 || unitGearLevel <= 0)
			{
				return 1f;
			}
			float num = (float)unitGearLevel / (float)playerGearLevel;
			float value = ((num >= 2f) ? 5f : ((num >= 1f) ? (1f + (num - 1f) * 4f) : ((!(num >= 0.5f)) ? 0.1f : (0.2f + (num - 0.5f) * 1.6f))));
			return Math.Clamp(value, 0.05f, 5f);
		}
	}
	public class HeatDecayService : IDisposable
	{
		private Timer? _factionTimer;

		private Timer? _regionTimer;

		public void Start()
		{
			int num = (int)(DyWorldConfig.DecayIntervalSeconds.Value * 1000f);
			_factionTimer = new Timer(delegate
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					HeatManager.Instance.DecayAll(DyWorldConfig.DecayAmountPerInterval.Value);
				});
			}, null, num, num);
			int num2 = (int)(DyWorldConfig.RegionDecayIntervalSeconds.Value * 1000f);
			_regionTimer = new Timer(delegate
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					HeatManager.Instance.DecayRegionAll(DyWorldConfig.RegionDecayAmountPerInterval.Value);
				});
			}, null, num2, num2);
		}

		public void Dispose()
		{
			_factionTimer?.Dispose();
			_regionTimer?.Dispose();
			_factionTimer = (_regionTimer = null);
		}
	}
	public class HeatManager
	{
		private readonly ConcurrentDictionary<ulong, PlayerHeatState> _states = new ConcurrentDictionary<ulong, PlayerHeatState>();

		private readonly Dictionary<(ulong, VRisingFaction), double> _lastKillNotify = new Dictionary<(ulong, VRisingFaction), double>();

		private readonly Dictionary<VRisingRegion, RegionHeatRecord> _globalRegionHeat = new Dictionary<VRisingRegion, RegionHeatRecord>();

		private readonly object _regionLock = new object();

		public static HeatManager Instance { get; } = new HeatManager();


		private HeatManager()
		{
		}

		public void AddKill(ulong steamId, VRisingFaction faction, float amount = 1f)
		{
			if (faction == VRisingFaction.Unknown)
			{
				return;
			}
			PlayerHeatState orCreate = GetOrCreate(steamId);
			HeatLevel heatLevel = GetHeatLevel(steamId, faction);
			lock (orCreate.FactionHeat)
			{
				orCreate.FactionHeat.TryGetValue(faction, out var value);
				value.HeatValue = Math.Min(value.HeatValue + amount, DyWorldConfig.MaximumHeatKills.Value * 1.5f);
				value.LastKillTimestamp = Timestamp();
				orCreate.FactionHeat[faction] = value;
			}
			HeatLevel heatLevel2 = GetHeatLevel(steamId, faction);
			if (heatLevel2 > heatLevel && DyWorldConfig.NotificationsEnabled.Value)
			{
				NotifyTierChange(steamId, faction, heatLevel2);
			}
			if (DyWorldConfig.NotificationsEnabled.Value)
			{
				FactionData data;
				string value2 = (FactionDatabase.TryGetData(faction, out data) ? data.DisplayName : faction.ToString());
				(ulong, VRisingFaction) key = (steamId, faction);
				double num = Timestamp();
				if (!_lastKillNotify.TryGetValue(key, out var value3) || num - value3 >= 3.0)
				{
					_lastKillNotify[key] = num;
					PlayerNotifier.Notify(steamId, $"+{amount:F0} heat with the {value2}.");
				}
			}
			if (DyWorldConfig.AllianceHeatEnabled.Value && FactionAlliances.TryGetAllies(faction, out AllianceEntry[] allies))
			{
				AllianceEntry[] array = allies;
				for (int i = 0; i < array.Length; i++)
				{
					AllianceEntry allianceEntry = array[i];
					AddKillSilent(steamId, allianceEntry.Ally, amount * allianceEntry.HeatShare);
				}
			}
		}

		private void AddKillSilent(ulong steamId, VRisingFaction faction, float amount)
		{
			if (faction == VRisingFaction.Unknown || amount <= 0f)
			{
				return;
			}
			PlayerHeatState orCreate = GetOrCreate(steamId);
			lock (orCreate.FactionHeat)
			{
				orCreate.FactionHeat.TryGetValue(faction, out var value);
				value.HeatValue = Math.Min(value.HeatValue + amount, DyWorldConfig.MaximumHeatKills.Value * 1.5f);
				value.LastKillTimestamp = Timestamp();
				orCreate.FactionHeat[faction] = value;
			}
		}

		public void SubtractKill(ulong steamId, VRisingFaction faction, float amount)
		{
			if (faction == VRisingFaction.Unknown || amount <= 0f || !_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return;
			}
			lock (value.FactionHeat)
			{
				if (value.FactionHeat.TryGetValue(faction, out var value2))
				{
					value2.HeatValue = Math.Max(0f, value2.HeatValue - amount);
					if (value2.HeatValue == 0f)
					{
						value.FactionHeat.Remove(faction);
					}
					else
					{
						value.FactionHeat[faction] = value2;
					}
				}
			}
		}

		public void ResetOnDeath(ulong steamId)
		{
			if (!_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return;
			}
			float value2 = DyWorldConfig.HeatDeathRetentionFactor.Value;
			lock (value.FactionHeat)
			{
				foreach (VRisingFaction item in value.FactionHeat.Keys.ToList())
				{
					FactionHeatRecord value3 = value.FactionHeat[item];
					float heatValue = value3.HeatValue;
					value3.HeatValue *= value2;
					if (DyWorldConfig.NotificationsEnabled.Value && heatValue >= DyWorldConfig.LowHeatKills.Value)
					{
						FactionData data;
						string text = (FactionDatabase.TryGetData(item, out data) ? data.DisplayName : item.ToString());
						if (value3.HeatValue < DyWorldConfig.LowHeatKills.Value)
						{
							PlayerNotifier.Notify(steamId, "The " + text + " have lost your trail.");
						}
						else
						{
							PlayerNotifier.Notify(steamId, $"The {text} still remember you. ({value3.HeatValue:F0} heat remaining)");
						}
					}
					if (value3.HeatValue <= 0f)
					{
						value.FactionHeat.Remove(item);
					}
					else
					{
						value.FactionHeat[item] = value3;
					}
				}
			}
		}

		public void DecayAll(float amount)
		{
			foreach (PlayerHeatState value in _states.Values)
			{
				lock (value.FactionHeat)
				{
					_ = value.FactionHeat.Count;
				}
				DecayDict(value.FactionHeat, amount);
			}
		}

		public HeatLevel GetHeatLevel(ulong steamId, VRisingFaction faction)
		{
			if (!_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return HeatLevel.None;
			}
			float heatValue;
			lock (value.FactionHeat)
			{
				if (!value.FactionHeat.TryGetValue(faction, out var value2))
				{
					return HeatLevel.None;
				}
				heatValue = value2.HeatValue;
			}
			return FactionLevel(heatValue);
		}

		public bool TryGetRecord(ulong steamId, VRisingFaction faction, out FactionHeatRecord record)
		{
			record = default(FactionHeatRecord);
			if (!_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return false;
			}
			lock (value.FactionHeat)
			{
				return value.FactionHeat.TryGetValue(faction, out record);
			}
		}

		public void SetRecord(ulong steamId, VRisingFaction faction, FactionHeatRecord record)
		{
			PlayerHeatState orCreate = GetOrCreate(steamId);
			lock (orCreate.FactionHeat)
			{
				orCreate.FactionHeat[faction] = record;
			}
		}

		public void UpdateSpawnTimestamp(ulong steamId, VRisingFaction faction, bool isBoss)
		{
			if (!_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return;
			}
			lock (value.FactionHeat)
			{
				if (value.FactionHeat.TryGetValue(faction, out var value2))
				{
					if (isBoss)
					{
						value2.LastBossSpawnTimestamp = Timestamp();
					}
					else
					{
						value2.LastSpawnTimestamp = Timestamp();
					}
					value.FactionHeat[faction] = value2;
				}
			}
		}

		public IReadOnlyDictionary<VRisingFaction, FactionHeatRecord> GetAllRecords(ulong steamId)
		{
			if (!_states.TryGetValue(steamId, out PlayerHeatState value))
			{
				return new Dictionary<VRisingFaction, FactionHeatRecord>();
			}
			lock (value.FactionHeat)
			{
				return new Dictionary<VRisingFaction, FactionHeatRecord>(value.FactionHeat);
			}
		}

		public void AddRegionKill(ulong steamId, VRisingRegion region, float amount = 1f)
		{
			if (region == VRisingRegion.Unknown)
			{
				return;
			}
			lock (_regionLock)
			{
				_globalRegionHeat.TryGetValue(region, out var value);
				value.HeatValue = Math.Min(value.HeatValue + amount, DyWorldConfig.RegionMaximumHeatKills.Value * 1.5f);
				value.LastKillTimestamp = Timestamp();
				_globalRegionHeat[region] = value;
			}
		}

		public void DecayRegionAll(float amount)
		{
			lock (_regionLock)
			{
				List<VRisingRegion> list = new List<VRisingRegion>();
				foreach (VRisingRegion item in _globalRegionHeat.Keys.ToList())
				{
					RegionHeatRecord value = _globalRegionHeat[item];
					value.HeatValue = Math.Max(0f, value.HeatValue - amount);
					if (value.HeatValue == 0f)
					{
						list.Add(item);
					}
					else
					{
						_globalRegionHeat[item] = value;
					}
				}
				foreach (VRisingRegion item2 in list)
				{
					_globalRegionHeat.Remove(item2);
				}
			}
		}

		public HeatLevel GetRegionHeatLevel(VRisingRegion region)
		{
			lock (_regionLock)
			{
				if (!_globalRegionHeat.TryGetValue(region, out var value))
				{
					return HeatLevel.None;
				}
				return RegionLevel(value.HeatValue);
			}
		}

		public HeatLevel GetRegionHeatLevel(ulong steamId, VRisingRegion region)
		{
			return GetRegionHeatLevel(region);
		}

		public bool TryGetRegionRecord(VRisingRegion region, out RegionHeatRecord record)
		{
			lock (_regionLock)
			{
				return _globalRegionHeat.TryGetValue(region, out record);
			}
		}

		public bool TryGetRegionRecord(ulong steamId, VRisingRegion region, out RegionHeatRecord record)
		{
			return TryGetRegionRecord(region, out record);
		}

		public void SetRegionRecord(VRisingRegion region, RegionHeatRecord record)
		{
			lock (_regionLock)
			{
				_globalRegionHeat[region] = record;
			}
		}

		public void SetRegionRecord(ulong steamId, VRisingRegion region, RegionHeatRecord record)
		{
			SetRegionRecord(region, record);
		}

		public void UpdateRegionSpawnTimestamp(VRisingRegion region, bool isGuardian)
		{
			lock (_regionLock)
			{
				if (_globalRegionHeat.TryGetValue(region, out var value))
				{
					if (isGuardian)
					{
						value.LastGuardianSpawnTimestamp = Timestamp();
					}
					else
					{
						value.LastSpawnTimestamp = Timestamp();
					}
					_globalRegionHeat[region] = value;
				}
			}
		}

		public void UpdateRegionSpawnTimestamp(ulong steamId, VRisingRegion region, bool isGuardian)
		{
			UpdateRegionSpawnTimestamp(region, isGuardian);
		}

		public IReadOnlyDictionary<VRisingRegion, RegionHeatRecord> GetAllRegionRecords()
		{
			lock (_regionLock)
			{
				return new Dictionary<VRisingRegion, RegionHeatRecord>(_globalRegionHeat);
			}
		}

		public IReadOnlyDictionary<VRisingRegion, RegionHeatRecord> GetAllRegionRecords(ulong steamId)
		{
			return GetAllRegionRecords();
		}

		public void LoadGlobalRegionState(Dictionary<VRisingRegion, RegionHeatRecord> records)
		{
			lock (_regionLock)
			{
				_globalRegionHeat.Clear();
				foreach (var (key, value) in records)
				{
					_globalRegionHeat[key] = value;
				}
			}
		}

		public IEnumerable<PlayerHeatState> GetAllStates()
		{
			return _states.Values;
		}

		public void LoadState(ulong steamId, Dictionary<VRisingFaction, FactionHeatRecord> factionRecords, Dictionary<VRisingRegion, RegionHeatRecord> regionRecords)
		{
			PlayerHeatState orCreate = GetOrCreate(steamId);
			lock (orCreate.FactionHeat)
			{
				orCreate.FactionHeat.Clear();
				foreach (var (key, value) in factionRecords)
				{
					orCreate.FactionHeat[key] = value;
				}
			}
			lock (orCreate.RegionHeat)
			{
				orCreate.RegionHeat.Clear();
				foreach (var (key2, value2) in regionRecords)
				{
					orCreate.RegionHeat[key2] = value2;
				}
			}
		}

		private PlayerHeatState GetOrCreate(ulong steamId)
		{
			return _states.GetOrAdd(steamId, (ulong id) => new PlayerHeatState
			{
				SteamId = id
			});
		}

		private static void DecayDict<TKey>(Dictionary<TKey, FactionHeatRecord> dict, float amount) where TKey : notnull
		{
			lock (dict)
			{
				List<TKey> list = new List<TKey>();
				foreach (TKey item in dict.Keys.ToList())
				{
					FactionHeatRecord value = dict[item];
					value.HeatValue = Math.Max(0f, value.HeatValue - amount);
					if (value.HeatValue == 0f)
					{
						list.Add(item);
					}
					else
					{
						dict[item] = value;
					}
				}
				foreach (TKey item2 in list)
				{
					dict.Remove(item2);
				}
			}
		}

		private static void DecayDict<TKey>(Dictionary<TKey, RegionHeatRecord> dict, float amount) where TKey : notnull
		{
			lock (dict)
			{
				List<TKey> list = new List<TKey>();
				foreach (TKey item in dict.Keys.ToList())
				{
					RegionHeatRecord value = dict[item];
					value.HeatValue = Math.Max(0f, value.HeatValue - amount);
					if (value.HeatValue == 0f)
					{
						list.Add(item);
					}
					else
					{
						dict[item] = value;
					}
				}
				foreach (TKey item2 in list)
				{
					dict.Remove(item2);
				}
			}
		}

		private static HeatLevel FactionLevel(float heat)
		{
			if (heat >= DyWorldConfig.MaximumHeatKills.Value)
			{
				return HeatLevel.Maximum;
			}
			if (heat >= DyWorldConfig.HighHeatKills.Value)
			{
				return HeatLevel.High;
			}
			if (heat >= DyWorldConfig.MediumHeatKills.Value)
			{
				return HeatLevel.Medium;
			}
			if (heat >= DyWorldConfig.LowHeatKills.Value)
			{
				return HeatLevel.Low;
			}
			return HeatLevel.None;
		}

		private static HeatLevel RegionLevel(float heat)
		{
			if (heat >= DyWorldConfig.RegionMaximumHeatKills.Value)
			{
				return HeatLevel.Maximum;
			}
			if (heat >= DyWorldConfig.RegionHighHeatKills.Value)
			{
				return HeatLevel.High;
			}
			if (heat >= DyWorldConfig.RegionMediumHeatKills.Value)
			{
				return HeatLevel.Medium;
			}
			if (heat >= DyWorldConfig.RegionLowHeatKills.Value)
			{
				return HeatLevel.Low;
			}
			return HeatLevel.None;
		}

		private static void NotifyTierChange(ulong steamId, VRisingFaction faction, HeatLevel level)
		{
			FactionData data;
			string text = (FactionDatabase.TryGetData(faction, out data) ? data.DisplayName : faction.ToString());
			string text2 = level switch
			{
				HeatLevel.Low => "The " + text + " have taken notice of you.", 
				HeatLevel.Medium => "The " + text + " are actively hunting you.", 
				HeatLevel.High => "The " + text + " have declared you an enemy. Expect reinforcements.", 
				HeatLevel.Maximum => "The " + text + " are sending their deadliest after you.", 
				_ => string.Empty, 
			};
			if (!string.IsNullOrEmpty(text2))
			{
				PlayerNotifier.Notify(steamId, text2);
			}
		}

		private static double Timestamp()
		{
			return (double)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000.0;
		}
	}
	public static class HuntTracker
	{
		private static readonly ConcurrentDictionary<Entity, HuntInfo> _tracked = new ConcurrentDictionary<Entity, HuntInfo>();

		public static int Count => _tracked.Count;

		public static void Register(Entity entity, ulong ownerSteamId, VRisingFaction faction, bool isVBlood = false, bool isSiegeWave = false)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			_tracked[entity] = new HuntInfo(ownerSteamId, faction, isVBlood, isSiegeWave);
		}

		public static bool TryGet(Entity entity, out HuntInfo info)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return _tracked.TryGetValue(entity, out info);
		}

		public static void Remove(Entity entity)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			_tracked.TryRemove(entity, out var _);
		}

		public static void Prune(EntityManager em)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			foreach (Entity item in _tracked.Keys.ToList())
			{
				if (!((EntityManager)(ref em)).Exists(item))
				{
					_tracked.TryRemove(item, out var _);
				}
			}
		}
	}
	public static class MainThreadDispatcher
	{
		private static readonly ConcurrentQueue<Action> _queue = new ConcurrentQueue<Action>();

		public static void Enqueue(Action action)
		{
			_queue.Enqueue(action);
		}

		public static void Drain()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			Action result;
			bool flag = default(bool);
			while (_queue.TryDequeue(out result))
			{
				try
				{
					result();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] MainThreadDispatcher: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogError(val);
				}
			}
		}
	}
	public static class PlayerNotifier
	{
		public static void Notify(ulong steamId, string message)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				World serverWorld = GetServerWorld();
				if (serverWorld == null)
				{
					return;
				}
				EntityManager entityManager = serverWorld.EntityManager;
				EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<User>() });
				NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					Enumerator<Entity> enumerator = val2.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(current);
						if (componentData.PlatformId == steamId)
						{
							SendToUser(entityManager, componentData, message);
							break;
						}
					}
				}
				finally
				{
					val2.Dispose();
					((EntityQuery)(ref val)).Dispose();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[DyWorld Rising] PlayerNotifier.Notify failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val3);
			}
		}

		public static void BroadcastToAll(string message)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				World serverWorld = GetServerWorld();
				if (serverWorld != null)
				{
					EntityManager entityManager = serverWorld.EntityManager;
					FixedString512Bytes val = default(FixedString512Bytes);
					((FixedString512Bytes)(ref val))..ctor(message);
					ServerChatUtils.SendSystemMessageToAllClients(entityManager, ref val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(55, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[DyWorld Rising] PlayerNotifier.BroadcastToAll failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}

		public static string GetPlayerName(ulong steamId)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				World serverWorld = GetServerWorld();
				if (serverWorld == null)
				{
					return "Unknown";
				}
				EntityManager entityManager = serverWorld.EntityManager;
				EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<User>() });
				NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					Enumerator<Entity> enumerator = val2.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(current);
						if (componentData.PlatformId == steamId)
						{
							return ((FixedString64Bytes)(ref componentData.CharacterName)).Value;
						}
					}
				}
				finally
				{
					val2.Dispose();
					((EntityQuery)(ref val)).Dispose();
				}
			}
			catch
			{
			}
			return "Unknown";
		}

		private static void SendToUser(EntityManager em, User user, string message)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			try
			{
				FixedString512Bytes val = default(FixedString512Bytes);
				((FixedString512Bytes)(ref val))..ctor(message);
				ServerChatUtils.SendSystemMessageToClient(em, user, ref val);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[DyWorld Rising] PlayerNotifier send failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}

		private static World? GetServerWorld()
		{
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current.Name == "Server")
				{
					return current;
				}
			}
			return null;
		}
	}
	public enum VRisingRegion
	{
		Unknown,
		FarbaneFoods,
		DunleyFarmlands,
		HallowedMountains,
		SilverlightHills,
		Gloomrot,
		CursedForest
	}
	public class RegionData
	{
		public string DisplayName { get; init; } = string.Empty;


		public float3 BoundsMin { get; init; }

		public float3 BoundsMax { get; init; }

		public VRisingFaction[] InhabitantFactions { get; init; } = Array.Empty<VRisingFaction>();


		public PrefabGUID[] GuardianUnits { get; init; } = Array.Empty<PrefabGUID>();

	}
	public static class RegionDatabase
	{
		private static readonly Dictionary<VRisingRegion, RegionData> _data = new Dictionary<VRisingRegion, RegionData>
		{
			[VRisingRegion.FarbaneFoods] = new RegionData
			{
				DisplayName = "Farbane Woods",
				BoundsMin = new float3(-3200f, -500f, -3200f),
				BoundsMax = new float3(200f, 500f, -400f),
				InhabitantFactions = new VRisingFaction[3]
				{
					VRisingFaction.Bandits,
					VRisingFaction.Blackfang,
					VRisingFaction.Creature
				},
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(2122229952),
					new PrefabGUID(-1905691330),
					new PrefabGUID(173259239)
				}
			},
			[VRisingRegion.DunleyFarmlands] = new RegionData
			{
				DisplayName = "Dunley Farmlands",
				BoundsMin = new float3(-1000f, -500f, -400f),
				BoundsMax = new float3(1800f, 500f, 1600f),
				InhabitantFactions = new VRisingFaction[4]
				{
					VRisingFaction.Militia,
					VRisingFaction.DunleyFarmers,
					VRisingFaction.Werewolves,
					VRisingFaction.Creature
				},
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(-29797003),
					new PrefabGUID(2079933370),
					new PrefabGUID(-1942352521)
				}
			},
			[VRisingRegion.HallowedMountains] = new RegionData
			{
				DisplayName = "Hallowed Mountains",
				BoundsMin = new float3(-3200f, -500f, -400f),
				BoundsMax = new float3(-1000f, 500f, 2200f),
				InhabitantFactions = new VRisingFaction[2]
				{
					VRisingFaction.ChurchOfLuminance,
					VRisingFaction.Undead
				},
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(-26105228),
					new PrefabGUID(153390636),
					new PrefabGUID(577478542)
				}
			},
			[VRisingRegion.SilverlightHills] = new RegionData
			{
				DisplayName = "Silverlight Hills",
				BoundsMin = new float3(1800f, -500f, -400f),
				BoundsMax = new float3(3600f, 500f, 2200f),
				InhabitantFactions = new VRisingFaction[2]
				{
					VRisingFaction.ChurchOfLuminance,
					VRisingFaction.Legion
				},
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(114912615),
					new PrefabGUID(-740796338),
					new PrefabGUID(495971434)
				}
			},
			[VRisingRegion.Gloomrot] = new RegionData
			{
				DisplayName = "Gloomrot",
				BoundsMin = new float3(-1000f, -500f, 1600f),
				BoundsMax = new float3(1800f, 500f, 3600f),
				InhabitantFactions = new VRisingFaction[1] { VRisingFaction.Gloomrot },
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(106480588),
					new PrefabGUID(-1101874342),
					new PrefabGUID(814083983)
				}
			},
			[VRisingRegion.CursedForest] = new RegionData
			{
				DisplayName = "Cursed Forest",
				BoundsMin = new float3(-3200f, -500f, 1600f),
				BoundsMax = new float3(-1000f, 500f, 3600f),
				InhabitantFactions = new VRisingFaction[4]
				{
					VRisingFaction.Undead,
					VRisingFaction.Werewolves,
					VRisingFaction.Cursed,
					VRisingFaction.Creature
				},
				GuardianUnits = (PrefabGUID[])(object)new PrefabGUID[3]
				{
					new PrefabGUID(939467639),
					new PrefabGUID(2079933370),
					new PrefabGUID(-910296704)
				}
			}
		};

		public static IEnumerable<VRisingRegion> AllRegions => _data.Keys;

		public static VRisingRegion GetRegion(float3 position)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			foreach (var (result, regionData2) in _data)
			{
				if (position.x >= regionData2.BoundsMin.x && position.x <= regionData2.BoundsMax.x && position.z >= regionData2.BoundsMin.z && position.z <= regionData2.BoundsMax.z)
				{
					return result;
				}
			}
			return VRisingRegion.Unknown;
		}

		public static bool TryGetData(VRisingRegion region, out RegionData data)
		{
			return _data.TryGetValue(region, out data);
		}
	}
	public static class RewardGiver
	{
		public static void GiveHunterKillReward(EntityManager em, ulong steamId, Entity killerCharEntity, float3 dropPosition, bool isVBlood)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//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_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!DyWorldConfig.RewardsEnabled.Value)
			{
				return;
			}
			try
			{
				int playerGearLevel = GearLevelHelper.GetPlayerGearLevel(em, killerCharEntity);
				int count = (isVBlood ? DyWorldConfig.VBloodKillRewardCount.Value : DyWorldConfig.HunterKillRewardCount.Value);
				float value = DyWorldConfig.NextTierBiasChance.Value;
				RewardEntry[] rewards = RewardTable.PickRewards(playerGearLevel, count, value);
				DeliverRewards(em, steamId, rewards);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] GiveHunterKillReward: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}

		public static void GiveSiegeReward(EntityManager em, ulong steamId, Entity charEntity, float3 dropPosition, int factionCount)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//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_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!DyWorldConfig.RewardsEnabled.Value)
			{
				return;
			}
			try
			{
				int playerGearLevel = GearLevelHelper.GetPlayerGearLevel(em, charEntity);
				int count = DyWorldConfig.SiegeBaseRewardCount.Value + Math.Max(0, factionCount - 1);
				float value = DyWorldConfig.NextTierBiasChance.Value;
				RewardEntry[] rewards = ScaleQuantities(RewardTable.PickRewards(playerGearLevel, count, value), 3);
				DeliverRewards(em, steamId, rewards);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] GiveSiegeReward: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}

		private static void DeliverRewards(EntityManager em, ulong steamId, RewardEntry[] rewards)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			Random random = new Random();
			World serverWorld = GetServerWorld();
			if (serverWorld == null)
			{
				return;
			}
			Entity val = FindCharEntity(em, steamId);
			if (!((EntityManager)(ref em)).Exists(val))
			{
				return;
			}
			ServerGameManager serverGameManager = serverWorld.GetExistingSystemManaged<ServerScriptMapper>().GetServerGameManager();
			bool flag = default(bool);
			for (int i = 0; i < rewards.Length; i++)
			{
				RewardEntry entry = rewards[i];
				PrefabGUID guid = RewardTable.Resolve(entry);
				if (((PrefabGUID)(ref guid)).GuidHash == 0)
				{
					continue;
				}
				int num = random.Next(entry.MinQty, entry.MaxQty + 1);
				bool num2 = TryAddToInventory(serverGameManager, val, guid, num);
				string value = entry.PrefabName.Replace("Item_Ingredient_", "").Replace("Item_Consumable_", "").Replace("Item_", "")
					.Replace("_", " ")
					.Trim();
				if (num2)
				{
					PlayerNotifier.Notify(steamId, $"Received: {num}x {value}");
					continue;
				}
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(38, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[DyWorld Rising] Could not give ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("x ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(entry.PrefabName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" to ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<ulong>(steamId);
				}
				log.LogWarning(val2);
			}
		}

		private static bool TryAddToInventory(ServerGameManager sgm, Entity charEntity, PrefabGUID guid, int qty)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			try
			{
				((ServerGameManager)(ref sgm)).TryAddInventoryItem(charEntity, guid, qty);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] TryAddInventoryItem failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
				return false;
			}
		}

		private static Entity FindCharEntity(EntityManager em, ulong steamId)
		{
			//IL_000a: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EntityQuery val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<User>() });
				NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					Enumerator<Entity> enumerator = val2.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						User componentData = ((EntityManager)(ref em)).GetComponentData<User>(current);
						if (componentData.PlatformId == steamId)
						{
							return componentData.LocalCharacter._Entity;
						}
					}
				}
				finally
				{
					val2.Dispose();
					((EntityQuery)(ref val)).Dispose();
				}
			}
			catch
			{
			}
			return Entity.Null;
		}

		private static RewardEntry[] ScaleQuantities(RewardEntry[] rewards, int multiplier)
		{
			RewardEntry[] array = new RewardEntry[rewards.Length];
			for (int i = 0; i < rewards.Length; i++)
			{
				RewardEntry rewardEntry = rewards[i];
				array[i] = new RewardEntry(rewardEntry.PrefabName, rewardEntry.FallbackHash, rewardEntry.MinQty * multiplier, rewardEntry.MaxQty * multiplier, rewardEntry.Weight);
			}
			return array;
		}

		private static World? GetServerWorld()
		{
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current.Name == "Server")
				{
					return current;
				}
			}
			return null;
		}
	}
	public readonly struct RewardEntry
	{
		public readonly string PrefabName;

		public readonly int FallbackHash;

		public readonly int MinQty;

		public readonly int MaxQty;

		public readonly int Weight;

		public RewardEntry(string name, int hash, int minQty, int maxQty, int weight = 10)
		{
			PrefabName = name;
			FallbackHash = hash;
			MinQty = minQty;
			MaxQty = maxQty;
			Weight = weight;
		}
	}
	public static class RewardTable
	{
		private static readonly Dictionary<string, PrefabGUID> _resolved = new Dictionary<string, PrefabGUID>();

		private static readonly RewardEntry[] Tier1 = new RewardEntry[7]
		{
			new RewardEntry("Item_BloodEssence_T01", 862477668, 2, 5, 25),
			new RewardEntry("Item_Ingredient_Bone", 1821405450, 3, 8, 20),
			new RewardEntry("Item_Ingredient_Leather", -1907572080, 2, 5, 20),
			new RewardEntry("Item_Ingredient_Whetstone", 1252507075, 1, 3, 15),
			new RewardEntry("Item_Consumable_HealingPotion_T01", 800879747, 1, 2, 15),
			new RewardEntry("Item_Ingredient_Mineral_CopperIngot", -1237019921, 2, 4, 15),
			new RewardEntry("Item_Ingredient_Gravedust", -608131642, 1, 3)
		};

		private static readonly RewardEntry[] Tier2 = new RewardEntry[7]
		{
			new RewardEntry("Item_Ingredient_Mineral_IronBar", -1750550553, 2, 5, 25),
			new RewardEntry("Item_BloodEssence_T02_Greater", 271594022, 1, 3, 20),
			new RewardEntry("Item_Ingredient_Gravedust", -608131642, 2, 5, 15),
			new RewardEntry("Item_Ingredient_PristineHide", 1658596502, 2, 4, 15),
			new RewardEntry("Item_Consumable_PhysicalPowerPotion_T02", -1568756102, 1, 2),
			new RewardEntry("Item_Ingredient_Mineral_Sulfur", 880699252, 2, 5),
			new RewardEntry("Item_Ingredient_BloodCrystal", -1913156733, 1, 2)
		};

		private static readonly RewardEntry[] Tier3 = new RewardEntry[6]
		{
			new RewardEntry("Item_Ingredient_Mineral_DarkSilverBar", -762000259, 2, 4, 25),
			new RewardEntry("Item_Ingredient_Spectraldust", -2130812821, 2, 5, 20),
			new RewardEntry("Item_Ingredient_Witchdust", -223452038, 2, 4, 15),
			new RewardEntry("Item_BloodEssence_T03_Primal", 1566989408, 1, 2, 15),
			new RewardEntry("Item_Ingredient_Crystal", -257494203, 2, 5, 15),
			new RewardEntry("Item_Ingredient_Coin_Silver", -949672483, 3, 8)
		};

		private static readonly RewardEntry[] Tier4 = new RewardEntry[7]
		{
			new RewardEntry("Item_BloodEssence_T03_Primal", 1566989408, 2, 4, 25),
			new RewardEntry("Item_Ingredient_Thread_Imperial", -898917584, 1, 3, 20),
			new RewardEntry("Item_Ingredient_Glass", -1233716303, 3, 6, 15),
			new RewardEntry("Item_Ingredient_Research_Paper", 780044299, 1, 2, 15),
			new RewardEntry("Item_Ingredient_TechScrap", 834864259, 2, 5, 15),
			new RewardEntry("Item_Ingredient_Vampiricdust", 805157024, 2, 4),
			new RewardEntry("Item_Ingredient_Coin_Silver", -949672483, 5, 12)
		};

		private static readonly RewardEntry[] Tier5 = new RewardEntry[7]
		{
			new RewardEntry("Item_BloodEssence_T03_Primal", 1566989408, 3, 6, 25),
			new RewardEntry("Item_Ingredient_OnyxTear", -651878258, 1, 2, 20),
			new RewardEntry("Item_Ingredient_Coin_Royal", -571562864, 2, 5, 15),
			new RewardEntry("Item_Ingredient_Thread_Imperial", -898917584, 2, 4, 15),
			new RewardEntry("Item_Ingredient_Gemdust", 820932258, 3, 6, 15),
			new RewardEntry("Item_Ingredient_TechScrap", 834864259, 3, 6),
			new RewardEntry("Item_Ingredient_Crystal", -257494203, 3, 7)
		};

		private static readonly RewardEntry[][] _tiers = new RewardEntry[5][] { Tier1, Tier2, Tier3, Tier4, Tier5 };

		public static int ResolvedCount => _resolved.Count;

		public static void AutoResolveItems(PrefabCollectionSystem prefabSystem)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			_resolved.Clear();
			Dictionary<string, PrefabGUID> dictionary = new Dictionary<string, PrefabGUID>(StringComparer.Ordinal);
			Enumerator<string, PrefabGUID> enumerator = prefabSystem.SpawnableNameToPrefabGuidDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, PrefabGUID> current = enumerator.Current;
				dictionary[current.Key] = current.Value;
			}
			if (dictionary.Count == 0)
			{
				Plugin.Log.LogWarning((object)"[DyWorld Rising] RewardTable: spawnable dict empty — items not resolved.");
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			RewardEntry[][] tiers = _tiers;
			bool flag = default(bool);
			foreach (RewardEntry[] array in tiers)
			{
				for (int j = 0; j < array.Length; j++)
				{
					RewardEntry rewardEntry = array[j];
					if (dictionary.TryGetValue(rewardEntry.PrefabName, out var value))
					{
						_resolved[rewardEntry.PrefabName] = value;
						if (((PrefabGUID)(ref value)).GuidHash != rewardEntry.FallbackHash)
						{
							ManualLogSource log = Plugin.Log;
							BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(60, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] Reward hash mismatch '");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(rewardEntry.PrefabName);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': hardcoded=");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(rewardEntry.FallbackHash);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" actual=");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((PrefabGUID)(ref value)).GuidHash);
							}
							log.LogWarning(val);
							num2++;
						}
						num++;
					}
					else
					{
						ManualLogSource log2 = Plugin.Log;
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(54, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DyWorld Rising] Reward item not in spawnable dict: '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(rewardEntry.PrefabName);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
						}
						log2.LogWarning(val);
						num3++;
					}
				}
			}
			ManualLogSource log3 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(65, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[DyWorld Rising] RewardTable: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" resolved, ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" mismatches, ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num3);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" not found.");
			}
			log3.LogInfo(val2);
		}

		public static int GetTierIndex(int gearLevel)
		{
			if (gearLevel <= 20)
			{
				return 0;
			}
			if (gearLevel <= 40)
			{
				return 1;
			}
			if (gearLevel <= 60)
			{
				return 2;
			}
			if (gearLevel <= 80)
			{
				return 3;
			}
			return 4;
		}

		public static RewardEntry[] PickRewards(int gearLevel, int count, float nextTierBias = 0.3f)
		{
			Random random = new Random();
			RewardEntry[] array = new RewardEntry[count];
			int tierIndex = GetTierIndex(gearLevel);
			for (int i = 0; i < count; i++)
			{
				bool flag = tierIndex < _tiers.Length - 1 && random.NextDouble() < (double)nextTierBias;
				array[i] = PickWeighted(_tiers[flag ? (tierIndex + 1) : tierIndex], random);
			}
			return array;
		}

		private static RewardEntry PickWeighted(RewardEntry[] pool, Random rng)
		{
			int maxValue = pool.Sum((RewardEntry e) => e.Weight);
			int num = rng.Next(maxValue);
			int num2 = 0;
			for (int i = 0; i < pool.Length; i++)
			{
				RewardEntry result = pool[i];
				num2 += result.Weight;
				if (num < num2)
				{
					return result;
				}
			}
			return pool[^1];
		}

		public static PrefabGUID Resolve(RewardEntry entry)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!_resolved.TryGetValue(entry.PrefabName, out var value))
			{
				return new PrefabGUID(entry.FallbackHash);
			}
			return value;
		}
	}
	public class SiegeManager
	{
		private readonly ConcurrentDictionary<ulong, SiegeState> _states = new ConcurrentDictionary<ulong, SiegeState>();

		public static SiegeManager Instance { get; } = new SiegeManager();


		private SiegeManager()
		{
		}

		public bool CanStartSiege(ulong steamId)
		{
			if (!_states.TryGetValue(steamId, out SiegeState value))
			{
				return true;
			}
			if (value.IsActive)
			{
				return false;
			}
			return Now() - value.LastSiegeEndTime >= (double)DyWorldConfig.SiegeCooldownSeconds.Value;
		}

		public SiegeState? GetState(ulong steamId)
		{
			if (!_states.TryGetValue(steamId, out SiegeState value))
			{
				return null;
			}
			return value;
		}

		public SiegeState StartSiege(ulong steamId, VRisingFaction[] factions, float3 castleCenter)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			SiegeState orAdd = _states.GetOrAdd(steamId, (ulong _) => new SiegeState
			{
				SteamId = steamId
			});
			SiegeState siegeState = new SiegeState
			{
				SteamId = steamId,
				SiegingFactions = factions,
				CurrentWave = 0,
				SiegeStartTime = Now(),
				WaveStartTime = Now(),
				CastleCenter = castleCenter,
				IsActive = true,
				LastSiegeEndTime = orAdd.LastSiegeEndTime
			};
			_states[steamId] = siegeState;
			return siegeState;
		}

		public void AdvanceWave(ulong steamId)
		{
			if (_states.TryGetValue(steamId, out SiegeState value) && value.IsActive)
			{
				value.CurrentWave++;
				value.WaveStartTime = Now();
			}
		}

		public void EndSiege(ulong steamId)
		{
			if (_states.TryGetValue(steamId, out SiegeState value))
			{
				value.IsActive = false;
				value.LastSiegeEndTime = Now();
			}
		}

		public IEnumerable<SiegeState> GetAllActive()
		{
			return _states.Values.Where((SiegeState s) => s.IsActive);
		}

		public void LoadCooldown(ulong steamId, double lastSiegeEndTime)
		{
			_states.GetOrAdd(steamId, (ulong _) => new SiegeState
			{
				SteamId = steamId
			}).LastSiegeEndTime = lastSiegeEndTime;
		}

		public IEnumerable<(ulong SteamId, double LastSiegeEndTime)> GetAllCooldownData()
		{
			return _states.Select<KeyValuePair<ulong, SiegeState>, (ulong, double)>((KeyValuePair<ulong, SiegeState> kvp) => (kvp.Key, kvp.Value.LastSiegeEndTime));
		}

		private static double Now()
		{
			return (double)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000.0;
		}
	}
	public class SiegeOrchestrator : IDisposable
	{
		private Timer? _timer;

		public void Start()
		{
			int num = (int)(DyWorldConfig.SiegeCheckIntervalSeconds.Value * 1000f);
			_timer = new Timer(delegate
			{
				MainThreadDispatcher.Enqueue(RunSiegeCheck);
			}, null, num, num);
		}

		private static void RunSiegeCheck()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (!DyWorldConfig.Enabled.Value || !DyWorldConfig.SiegeEnabled.Value)
			{
				return;
			}
			try
			{
				World serverWorld = GetServerWorld();
				if (serverWorld == null)
				{
					return;
				}
				E