Decompiled source of DeepRising v0.1.0

plugins/DeepRising/DeepRising.Client.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DeepRising.CustomItems;
using DeepRising.Probe;
using DeepRising.Shared;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Network;
using ProjectM.Shared;
using ProjectM.Terrain;
using ProjectM.UI;
using Stunlock.Core;
using Stunlock.Localization;
using Stunlock.Network;
using TMPro;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DeepRising.Client")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+60570d036cb645189aa435c34b42d7162430cee3")]
[assembly: AssemblyProduct("DeepRising.Client")]
[assembly: AssemblyTitle("DeepRising.Client")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[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]
	[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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DeepRising.Probe
{
	internal static class FrameTimings
	{
		private sealed class Part
		{
			public long Calls;

			public long Ticks;

			public long MaxTicks;

			public long FrameTicks;
		}

		private const double SlowModMilliseconds = 3.0;

		private const double SlowFrameMilliseconds = 50.0;

		private const double SummarySeconds = 60.0;

		private const int MaxSlowFramesPerSummary = 20;

		private static readonly double TicksPerMillisecond = (double)Stopwatch.Frequency / 1000.0;

		private static readonly Dictionary<string, Part> Parts = new Dictionary<string, Part>();

		private static long _frameStart;

		private static long _summaryStart;

		private static int _slowFrames;

		private static int _frames;

		private static long _longestFrame;

		public static bool Enabled;

		public static Action<string> Log = delegate
		{
		};

		public static long Start()
		{
			if (!Enabled)
			{
				return 0L;
			}
			return Stopwatch.GetTimestamp();
		}

		public static void Stop(string name, long started)
		{
			if (Enabled && started != 0L)
			{
				long num = Stopwatch.GetTimestamp() - started;
				if (!Parts.TryGetValue(name, out var value))
				{
					value = (Parts[name] = new Part());
				}
				value.Calls++;
				value.Ticks += num;
				value.FrameTicks += num;
				if (num > value.MaxTicks)
				{
					value.MaxTicks = num;
				}
			}
		}

		public static void EndFrame(string side)
		{
			if (!Enabled)
			{
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			if (_summaryStart == 0L)
			{
				_summaryStart = timestamp;
			}
			long num = ((_frameStart == 0L) ? 0 : (timestamp - _frameStart));
			_frameStart = timestamp;
			_frames++;
			if (num > _longestFrame)
			{
				_longestFrame = num;
			}
			long num2 = 0L;
			foreach (Part value in Parts.Values)
			{
				num2 += value.FrameTicks;
			}
			bool flag = (double)num2 / TicksPerMillisecond >= 3.0;
			bool flag2 = (double)num / TicksPerMillisecond >= 50.0;
			if ((flag || flag2) && _slowFrames++ < 20)
			{
				StringBuilder stringBuilder = new StringBuilder($"[timings {side}] {(flag ? "slow mod" : "long frame")}: frame {(double)num / TicksPerMillisecond:F1} ms, the mod's {(double)num2 / TicksPerMillisecond:F2} ms");
				foreach (KeyValuePair<string, Part> part in Parts)
				{
					if ((double)part.Value.FrameTicks / TicksPerMillisecond >= 0.1)
					{
						StringBuilder stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder3 = stringBuilder2;
						StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2);
						handler.AppendLiteral(", ");
						handler.AppendFormatted(part.Key);
						handler.AppendLiteral(" ");
						handler.AppendFormatted((double)part.Value.FrameTicks / TicksPerMillisecond, "F2");
						stringBuilder3.Append(ref handler);
					}
				}
				Log(stringBuilder.ToString());
			}
			foreach (Part value2 in Parts.Values)
			{
				value2.FrameTicks = 0L;
			}
			if ((double)(timestamp - _summaryStart) / (double)Stopwatch.Frequency < 60.0)
			{
				return;
			}
			StringBuilder stringBuilder4 = new StringBuilder($"[timings {side}] {_frames} frames in {(double)(timestamp - _summaryStart) / (double)Stopwatch.Frequency:F0} s, longest {(double)_longestFrame / TicksPerMillisecond:F1} ms, {_slowFrames} slow;");
			foreach (KeyValuePair<string, Part> part2 in Parts)
			{
				StringBuilder stringBuilder2 = stringBuilder4;
				StringBuilder stringBuilder5 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(18, 4, stringBuilder2);
				handler.AppendLiteral(" ");
				handler.AppendFormatted(part2.Key);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(part2.Value.Calls);
				handler.AppendLiteral("x avg ");
				handler.AppendFormatted((double)part2.Value.Ticks / TicksPerMillisecond / (double)Math.Max(1L, part2.Value.Calls), "F3");
				handler.AppendLiteral(" max ");
				handler.AppendFormatted((double)part2.Value.MaxTicks / TicksPerMillisecond, "F2");
				handler.AppendLiteral(" ms;");
				stringBuilder5.Append(ref handler);
			}
			Log(stringBuilder4.ToString());
			Parts.Clear();
			_summaryStart = timestamp;
			_frames = 0;
			_slowFrames = 0;
			_longestFrame = 0L;
		}
	}
	internal static class InventoryProbe
	{
		private const int MaxSlotLines = 60;

		private const uint FnvOffsetBasis = 2166136261u;

		private const uint FnvPrime = 16777619u;

		public unsafe static List<string> DescribeCustomItems(World world)
		{
			//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)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			EntityManager entityManager = world.EntityManager;
			GameDataSystem existingSystemManaged = world.GetExistingSystemManaged<GameDataSystem>();
			PrefabGUID[] array = NativeItemTable.Read(world);
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			if (array == null)
			{
				list.Add("item table: none in this world");
			}
			else
			{
				uint num = 2166136261u;
				for (int i = 0; i < array.Length; i++)
				{
					dictionary[((PrefabGUID)(ref array[i])).GuidHash] = i;
					num = (num ^ (uint)((PrefabGUID)(ref array[i])).GuidHash) * 16777619;
				}
				bool value = true;
				for (int j = 1; j < array.Length; j++)
				{
					if (((PrefabGUID)(ref array[j - 1])).GuidHash > ((PrefabGUID)(ref array[j])).GuidHash)
					{
						value = false;
					}
				}
				list.Add($"item table: {array.Length} items, order hash {num:X8}, sorted by guid: {value}");
			}
			ComponentType val = ComponentType.ReadOnly(Il2CppType.Of<InventoryBuffer>());
			int num2 = Marshal.SizeOf<InventoryBuffer>();
			EntityQueryBuilder val2 = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
			val2 = ((EntityQueryBuilder)(ref val2)).AddAll(val);
			EntityQueryBuilder val3 = ((EntityQueryBuilder)(ref val2)).WithOptions((EntityQueryOptions)2);
			EntityQuery val4 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val3);
			((EntityQueryBuilder)(ref val3)).Dispose();
			NativeArray<Entity> val5 = ((EntityQuery)(ref val4)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
			try
			{
				int num3 = 0;
				int num4 = 0;
				Enumerator<Entity> enumerator = val5.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Entity current = enumerator.Current;
					int bufferLength = ((EntityManager)(ref entityManager)).GetBufferLength(current, val.TypeIndex);
					byte* bufferRawRO = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRO(current, val.TypeIndex);
					for (int k = 0; k < bufferLength; k++)
					{
						InventoryBuffer val6 = Marshal.PtrToStructure<InventoryBuffer>(new IntPtr(bufferRawRO + k * num2));
						CustomItemDefinition customItemDefinition = CustomItemCatalog.Find(val6.ItemType);
						if (customItemDefinition != null)
						{
							num3++;
							num4 += val6.Amount;
							if (num3 <= 60)
							{
								int value3;
								string value2 = (dictionary.TryGetValue(((PrefabGUID)(ref val6.ItemType)).GuidHash, out value3) ? value3.ToString() : "none");
								list.Add($"inventory {current.Index} slot {k}: {customItemDefinition.PrefabName} x{val6.Amount}, table index {value2}{DescribeUiName(existingSystemManaged, val6.ItemType)}");
							}
						}
					}
				}
				list.Add($"{num3} slots hold {num4} custom items in {val5.Length} inventories");
				return list;
			}
			finally
			{
				val5.Dispose();
				((EntityQuery)(ref val4)).Dispose();
			}
		}

		private static string DescribeUiName(GameDataSystem gameData, PrefabGUID guid)
		{
			//IL_0014: 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)
			if (!CustomItemRegistry.IsClient)
			{
				return "";
			}
			try
			{
				ManagedItemData orDefaultWithoutLogging = gameData.ManagedDataRegistry.GetOrDefaultWithoutLogging<ManagedItemData>(guid, (ManagedItemData)null);
				return (orDefaultWithoutLogging == null) ? ", UI name: NONE" : $", UI name '{Localization.Get(orDefaultWithoutLogging.Name, false)}', icon {(Object)(object)orDefaultWithoutLogging.Icon != (Object)null}";
			}
			catch (Exception ex)
			{
				return ", UI name check failed: " + ex.GetType().Name;
			}
		}
	}
}
namespace DeepRising.CustomItems
{
	internal struct BrewStat
	{
		public UnitStatType Stat;

		public float Value;

		public BrewStatUnit Unit;

		public BrewStat(UnitStatType stat, float value, BrewStatUnit unit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Stat = stat;
			Value = value;
			Unit = unit;
		}
	}
	internal enum BrewStatUnit
	{
		Percent,
		Points,
		Immunity
	}
	internal enum BrewFamily
	{
		Hunt,
		Blood,
		Shadow,
		Slaughter
	}
	internal sealed class BrewDefinition
	{
		public string Name;

		public BrewFamily Family;

		public int Tier;

		public string DisplayName;

		public string DisplayNamePl;

		public string Fish;

		public string EssenceItem;

		public int EssenceAmount;

		public float DurationSeconds;

		public bool PersistsThroughDeath;

		public string UnlockTech;

		public BrewStat[] Stats;

		public IconTint IconTint;

		public PrefabGUID GroupGuid;

		public PrefabGUID CastGuid;

		public PrefabGUID ActivateGuid;

		public PrefabGUID BuffGuid;

		public string ItemPrefabName => "Item_Consumable_DeepRising_Brew_" + Name;

		public string GroupPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_AbilityGroup";

		public string CastPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Cast";

		public string ActivatePrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Activate";

		public string BuffPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Buff";
	}
	internal static class BrewCatalog
	{
		private const int FirstGuid = 1146181585;

		private const int PrefabsPerBrew = 4;

		public const string ItemPrefabPrefix = "Item_Consumable_DeepRising_Brew_";

		public const string AbilityPrefabPrefix = "AB_Consumable_DeepRising_Brew_";

		public const string SourceItem = "Item_Consumable_PhysicalPowerPotion_T01";

		public const string SourceGroup = "AB_Consumable_PhysicalPowerPotion_T01_AbilityGroup";

		public const string SourceCast = "AB_Consumable_PhysicalPowerPotion_T01_Cast";

		public const string SourceActivate = "AB_Consumable_PhysicalPowerPotion_T01_Activate";

		public const string SourceBuff = "AB_Consumable_PhysicalPowerPotion_T01_Buff";

		private const string BloodEssence = "Item_BloodEssence_T01";

		private const int TierCount = 3;

		private const float SecondsPerMinute = 60f;

		private static readonly string[] TierNumerals = new string[3] { "I", "II", "III" };

		public static readonly (int Tier, VBloodTeacher Teacher)[] Teachers = new(int, VBloodTeacher)[3]
		{
			(1, VBloodTeachers.Finn),
			(2, VBloodTeachers.Raziel),
			(3, VBloodTeachers.Henry)
		};

		private const int PersistingTier = 3;

		private const float GarlicImmunity = 1000f;

		private static readonly List<(BrewDefinition Brew, Func<int, BrewStat[]> StatsOfTier)> Makers = new List<(BrewDefinition, Func<int, BrewStat[]>)>();

		public static readonly BrewDefinition[] All = Build();

		private const float PercentPerUnit = 100f;

		private const string HighlightOpen = "<color=#82C9D9>";

		private const string HighlightClose = "</color>";

		private static GearBalance Values => GearBalance.Current;

		public static string TierNumeral(int tier)
		{
			return TierNumerals[tier - 1];
		}

		public static BrewDefinition FindByItem(string itemPrefabName)
		{
			BrewDefinition[] all = All;
			foreach (BrewDefinition brewDefinition in all)
			{
				if (brewDefinition.ItemPrefabName == itemPrefabName)
				{
					return brewDefinition;
				}
			}
			return null;
		}

		public static BrewDefinition FirstOfTier(int tier)
		{
			BrewDefinition[] all = All;
			foreach (BrewDefinition brewDefinition in all)
			{
				if (brewDefinition.Tier == tier)
				{
					return brewDefinition;
				}
			}
			return null;
		}

		public static bool IsBrewBuff(PrefabGUID guid)
		{
			BrewDefinition[] all = All;
			for (int i = 0; i < all.Length; i++)
			{
				if (((PrefabGUID)(ref all[i].BuffGuid)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash)
				{
					return true;
				}
			}
			return false;
		}

		private static BrewDefinition[] Build()
		{
			List<BrewDefinition> brews = new List<BrewDefinition>();
			AddFamily(BrewFamily.Hunt, "Hunt", "Brew of the Hunt", "Wywar Łowów", 0.27f, new string[3] { "AshgillPerch", "GravetoothPike", "OldMossback" }, (int tier) => new BrewStat[1]
			{
				new BrewStat((UnitStatType)3, Values.BrewYieldBonus[tier], BrewStatUnit.Percent)
			});
			AddFamily(BrewFamily.Blood, "Blood", "Brew of Blood", "Wywar Krwi", 0.98f, new string[3] { "VeinfinMinnow", "CrimsonEel", "CrimsonMatriarch" }, (int tier) => new BrewStat[1]
			{
				new BrewStat((UnitStatType)81, Values.BrewBloodDrainReduction[tier], BrewStatUnit.Percent)
			});
			AddFamily(BrewFamily.Shadow, "Shadow", "Brew of Shadow", "Wywar Cienia", 0.74f, new string[3] { "DuskscaleCarp", "EclipseKoi", "ArgentLeviathan" }, (int tier) => new BrewStat[3]
			{
				Resistance((UnitStatType)19, Values.BrewSunResistance[tier]),
				Resistance((UnitStatType)10, Values.BrewHolyResistance[tier]),
				Resistance((UnitStatType)20, Values.BrewGarlicResistance[tier])
			});
			AddFamily(BrewFamily.Slaughter, "Slaughter", "Brew of Slaughter", "Wywar Mordu", 0.6f, new string[3] { "IronjawChub", "StormgillSturgeon", "Voltfang" }, (int tier) => new BrewStat[2]
			{
				new BrewStat((UnitStatType)67, Values.BrewPowerBonus[tier], BrewStatUnit.Percent),
				new BrewStat((UnitStatType)68, Values.BrewPowerBonus[tier], BrewStatUnit.Percent)
			});
			return brews.ToArray();
			void AddFamily(BrewFamily family, string name, string displayName, string displayNamePl, float hue, string[] fish, Func<int, BrewStat[]> statsOfTier)
			{
				//IL_00be: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < 3; i++)
				{
					int num = 1146181585 + brews.Count * 4;
					BrewDefinition brewDefinition = new BrewDefinition
					{
						Name = name + (i + 1),
						Family = family,
						Tier = i + 1,
						DisplayName = displayName + " " + TierNumerals[i],
						DisplayNamePl = displayNamePl + " " + TierNumerals[i],
						Fish = fish[i],
						EssenceItem = "Item_BloodEssence_T01",
						PersistsThroughDeath = (i + 1 >= 3),
						UnlockTech = CustomTechCatalog.BrewTechName(i + 1),
						IconTint = new IconTint(hue, 1f),
						GroupGuid = new PrefabGUID(num),
						CastGuid = new PrefabGUID(num + 1),
						ActivateGuid = new PrefabGUID(num + 2),
						BuffGuid = new PrefabGUID(num + 3)
					};
					brews.Add(brewDefinition);
					Makers.Add((brewDefinition, statsOfTier));
					Fill(brewDefinition, statsOfTier);
				}
			}
		}

		private static BrewStat Resistance(UnitStatType stat, float points)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new BrewStat(stat, points, (!(points >= 1000f)) ? BrewStatUnit.Points : BrewStatUnit.Immunity);
		}

		private static void Fill(BrewDefinition brew, Func<int, BrewStat[]> statsOfTier)
		{
			int num = brew.Tier - 1;
			brew.EssenceAmount = Math.Max(1, (int)Math.Round(Values.BrewEssenceAmount[num]));
			brew.DurationSeconds = Values.BrewDurationMinutes[num] * 60f;
			brew.Stats = statsOfTier(num);
		}

		public static void Refresh()
		{
			_ = All;
			foreach (var maker in Makers)
			{
				Fill(maker.Brew, maker.StatsOfTier);
			}
		}

		public static string DescriptionOf(BrewDefinition brew, bool polish)
		{
			List<string> list = new List<string>();
			BrewStat[] stats = brew.Stats;
			foreach (BrewStat stat in stats)
			{
				list.Add(EffectText(stat, polish));
			}
			string value = $"{"<color=#82C9D9>"}{brew.DurationSeconds / 60f:0}{"</color>"}";
			if (polish)
			{
				return $"Wywar z ryby i esencji krwi. {string.Join(", ", list)} przez {value} min." + (brew.PersistsThroughDeath ? " Działa dalej po śmierci." : " Kończy się wraz ze śmiercią.") + " Naraz działa tylko jeden wywar.";
			}
			return $"A brew of fish and blood essence. {string.Join(", ", list)} for {value} minutes." + (brew.PersistsThroughDeath ? " It lasts through death." : " It ends with death.") + " Only one brew is active at a time.";
		}

		private static string EffectText(BrewStat stat, bool polish)
		{
			return EffectText(stat, polish, highlighted: true);
		}

		public static string Highlight(string text)
		{
			return "<color=#82C9D9>" + text + "</color>";
		}

		public static string EffectText(BrewStat stat, bool polish, bool highlighted)
		{
			//IL_0021: 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_004b: Invalid comparison between Unknown and I4
			string value = (highlighted ? "<color=#82C9D9>" : string.Empty);
			string value2 = (highlighted ? "</color>" : string.Empty);
			string value3 = StatName(stat.Stat, polish);
			switch (stat.Unit)
			{
			case BrewStatUnit.Percent:
			{
				string value4 = (((int)stat.Stat == 81) ? "-" : "+");
				return $"{value3} {value}{value4}{stat.Value * 100f:0.#}%{value2}";
			}
			case BrewStatUnit.Immunity:
				return $"{value3}: {value}{(polish ? "niewrażliwość" : "immunity")}{value2}";
			default:
				return $"{value3} {value}+{stat.Value:0}{value2}";
			}
		}

		private unsafe static string StatName(UnitStatType stat, bool polish)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			if ((int)stat <= 19)
			{
				if ((int)stat <= 10)
				{
					if ((int)stat == 3)
					{
						if (!polish)
						{
							return "Resource yield";
						}
						return "Zbiór surowców";
					}
					if ((int)stat == 10)
					{
						if (!polish)
						{
							return "Holy resistance";
						}
						return "Odporność na świętość";
					}
				}
				else
				{
					if ((int)stat == 11)
					{
						if (!polish)
						{
							return "Silver resistance";
						}
						return "Odporność na srebro";
					}
					if ((int)stat == 19)
					{
						if (!polish)
						{
							return "Sun resistance";
						}
						return "Odporność na słońce";
					}
				}
			}
			else if ((int)stat <= 67)
			{
				if ((int)stat == 20)
				{
					if (!polish)
					{
						return "Garlic resistance";
					}
					return "Odporność na czosnek";
				}
				if ((int)stat == 67)
				{
					if (!polish)
					{
						return "Physical power";
					}
					return "Moc fizyczna";
				}
			}
			else
			{
				if ((int)stat == 68)
				{
					if (!polish)
					{
						return "Spell power";
					}
					return "Moc zaklęć";
				}
				if ((int)stat == 81)
				{
					if (!polish)
					{
						return "Blood drain";
					}
					return "Zużycie krwi";
				}
			}
			return ((object)(*(UnitStatType*)(&stat))/*cast due to .constrained prefix*/).ToString();
		}
	}
	internal static class CustomBrewRegistry
	{
		private const DropTriggerType NoDropTrigger = (DropTriggerType)7;

		private static readonly string[] SourceNames = new string[4] { "AB_Consumable_PhysicalPowerPotion_T01_AbilityGroup", "AB_Consumable_PhysicalPowerPotion_T01_Cast", "AB_Consumable_PhysicalPowerPotion_T01_Activate", "AB_Consumable_PhysicalPowerPotion_T01_Buff" };

		public static readonly SortedSet<string> Repointed = new SortedSet<string>();

		public static readonly SortedSet<string> LeftOut = new SortedSet<string>();

		public const float Forever = 0f;

		public static Func<World, string> BuffBarWriter;

		public static string TryRegisterPrefabs(World world, Action<string> trace)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = world.EntityManager;
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			PrefabLookupMap prefabLookupMap = existingSystemManaged._PrefabLookupMap;
			Entity[] array = (Entity[])(object)new Entity[SourceNames.Length];
			PrefabGUID[] array2 = (PrefabGUID[])(object)new PrefabGUID[SourceNames.Length];
			for (int i = 0; i < SourceNames.Length; i++)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(SourceNames[i], ref array2[i], false))
				{
					return "the game has no prefab " + SourceNames[i];
				}
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetValueWithoutLogging(array2[i], ref array[i]))
				{
					return SourceNames[i] + " has no entity yet";
				}
			}
			BrewDefinition[] all = BrewCatalog.All;
			PrefabGUID val = default(PrefabGUID);
			Entity val2 = default(Entity);
			foreach (BrewDefinition brewDefinition in all)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val, false) || !existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val, ref val2))
				{
					return "the item " + brewDefinition.ItemPrefabName + " is not registered";
				}
			}
			all = BrewCatalog.All;
			PrefabGUID val7 = default(PrefabGUID);
			Entity val8 = default(Entity);
			Entity val9 = default(Entity);
			foreach (BrewDefinition brewDefinition2 in all)
			{
				trace("[" + world.Name + "] building the brew " + brewDefinition2.Name);
				Entity val3 = CloneOnce(world, existingSystemManaged, array[0], array2[0], brewDefinition2.GroupGuid, brewDefinition2.GroupPrefabName);
				Entity val4 = CloneOnce(world, existingSystemManaged, array[1], array2[1], brewDefinition2.CastGuid, brewDefinition2.CastPrefabName);
				Entity val5 = CloneOnce(world, existingSystemManaged, array[2], array2[2], brewDefinition2.ActivateGuid, brewDefinition2.ActivatePrefabName);
				Entity val6 = CloneOnce(world, existingSystemManaged, array[3], array2[3], brewDefinition2.BuffGuid, brewDefinition2.BuffPrefabName);
				((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition2.ItemPrefabName, ref val7, false);
				existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val7, ref val8);
				if (Present<CastAbilityOnConsume>(entityManager, val8))
				{
					SetGuid<CastAbilityOnConsume>(entityManager, val8, "AbilityGuid", brewDefinition2.GroupGuid);
				}
				if (PresentWithElements<AbilityGroupStartAbilitiesBuffer>(entityManager, val3))
				{
					SetGuidInBuffer<AbilityGroupStartAbilitiesBuffer>(entityManager, val3, "PrefabGUID", brewDefinition2.CastGuid);
				}
				if (Present<AbilityState>(entityManager, val4))
				{
					SetGuid<AbilityState>(entityManager, val4, "AbilityId", brewDefinition2.CastGuid);
				}
				if (PresentWithElements<AbilitySpawnPrefabOnCast>(entityManager, val4))
				{
					SetGuidInBuffer<AbilitySpawnPrefabOnCast>(entityManager, val4, "SpawnPrefab", brewDefinition2.ActivateGuid);
				}
				if (PresentWithElements<ApplyBuffOnGameplayEvent>(entityManager, val5))
				{
					SetGuidInBuffer<ApplyBuffOnGameplayEvent>(entityManager, val5, "Buff0", brewDefinition2.BuffGuid);
				}
				if (PresentWithElements<DropFromTablesOnGameplayEvent>(entityManager, val5))
				{
					DropFromTablesOnGameplayEvent value = ReadElement<DropFromTablesOnGameplayEvent>(entityManager, val5, 0);
					value.DropTrigger = (DropTriggerType)7;
					WriteElement<DropFromTablesOnGameplayEvent>(entityManager, val5, 0, value);
				}
				WriteBuff(world, val6, brewDefinition2.DurationSeconds, brewDefinition2.PersistsThroughDeath, removableByPlayer: true, brewDefinition2.Stats, brewDefinition2.Name, trace);
				PrefabGUID[] array3 = (PrefabGUID[])(object)new PrefabGUID[5]
				{
					SourceItemGuid(prefabLookupMap),
					array2[0],
					array2[1],
					array2[2],
					array2[3]
				};
				PrefabGUID[] array4 = (PrefabGUID[])(object)new PrefabGUID[5] { val7, brewDefinition2.GroupGuid, brewDefinition2.CastGuid, brewDefinition2.ActivateGuid, brewDefinition2.BuffGuid };
				((PrefabLookupMap)(ref prefabLookupMap)).TryGetValueWithoutLogging(array3[0], ref val9);
				Entity[] array5 = (Entity[])(object)new Entity[5]
				{
					val9,
					array[0],
					array[1],
					array[2],
					array[3]
				};
				Entity[] array6 = (Entity[])(object)new Entity[5] { val8, val3, val4, val5, val6 };
				Entity[] array7 = (Entity[])(object)new Entity[4] { val3, val4, val5, val6 };
				foreach (Entity entity in array7)
				{
					for (int l = 0; l < array3.Length; l++)
					{
						foreach (string item in PrefabMemory.Find(entityManager, entity, array3[l], array4[l]))
						{
							Repointed.Add(item);
						}
						if (((Entity)(ref array5[l])).Equals(Entity.Null))
						{
							continue;
						}
						foreach (string item2 in PrefabMemory.FindEntity(entityManager, entity, array5[l], array6[l]))
						{
							Repointed.Add(item2 + " (entity)");
						}
					}
				}
			}
			SealDefinition[] all2 = SealCatalog.All;
			foreach (SealDefinition sealDefinition in all2)
			{
				trace("[" + world.Name + "] building the seal " + sealDefinition.Name);
				Entity buff = CloneOnce(world, existingSystemManaged, array[3], array2[3], sealDefinition.BuffGuid, sealDefinition.BuffPrefabName);
				WriteBuff(world, buff, 0f, persistsThroughDeath: true, removableByPlayer: false, sealDefinition.Stats, sealDefinition.Name, trace);
			}
			CloneOnce(world, existingSystemManaged, array[3], array2[3], SealCatalog.SetBuffGuid, "Buff_DeepRising_Seal_Complete");
			WriteSealSet(world, trace);
			if (Repointed.Count > 0)
			{
				trace("[" + world.Name + "] repointed to the brews' own links: " + string.Join(", ", Repointed));
			}
			if (LeftOut.Count > 0)
			{
				trace("[" + world.Name + "] not on this side's prefabs, left out: " + string.Join(", ", LeftOut));
			}
			return null;
		}

		private static PrefabGUID SourceItemGuid(PrefabLookupMap lookup)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			PrefabGUID result = default(PrefabGUID);
			((PrefabLookupMap)(ref lookup)).TryGetPrefabGuidWithName("Item_Consumable_PhysicalPowerPotion_T01", ref result, false);
			return result;
		}

		private static bool Present<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_0002: 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)
			if (((EntityManager)(ref entityManager)).HasComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0)))
			{
				return true;
			}
			if (!CustomItemRegistry.IsClient)
			{
				throw new InvalidOperationException(typeof(T).Name + " is not on the prefab it is to be changed on");
			}
			LeftOut.Add(typeof(T).Name);
			return false;
		}

		private static bool PresentWithElements<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			if (!Present<T>(entityManager, entity))
			{
				return false;
			}
			if (BufferLength<T>(entityManager, entity) > 0)
			{
				return true;
			}
			if (!CustomItemRegistry.IsClient)
			{
				throw new InvalidOperationException(typeof(T).Name + " is empty on the prefab it is to be changed on");
			}
			LeftOut.Add(typeof(T).Name);
			return false;
		}

		public static void WriteSealSet(World world, Action<string> trace)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			Entity buff = default(Entity);
			if (world.GetExistingSystemManaged<PrefabCollectionSystem>()._PrefabGuidToEntityMap.TryGetValue(SealCatalog.SetBuffGuid, ref buff))
			{
				WriteBuff(world, buff, 0f, persistsThroughDeath: true, removableByPlayer: false, SealCatalog.SetStats(), "Buff_DeepRising_Seal_Complete", trace);
			}
		}

		private static Entity CloneOnce(World world, PrefabCollectionSystem prefabs, Entity source, PrefabGUID sourceGuid, PrefabGUID guid, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			Entity result = default(Entity);
			if (!prefabs._PrefabGuidToEntityMap.TryGetValue(guid, ref result))
			{
				return PrefabCloner.Clone(world, source, sourceGuid, guid, name, ownAsset: true);
			}
			return result;
		}

		private static void WriteBuff(World world, Entity buff, float durationSeconds, bool persistsThroughDeath, bool removableByPlayer, BrewStat[] stats, string name, Action<string> trace)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0060: 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_004d: 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_0031: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0058: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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)
			//IL_00a1: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = world.EntityManager;
			if (Present<LifeTime>(entityManager, buff))
			{
				LifeTime value = Read<LifeTime>(entityManager, buff);
				value.Duration = durationSeconds;
				if (durationSeconds == 0f)
				{
					value.EndAction = (LifeTimeEndAction)0;
				}
				Write<LifeTime>(entityManager, buff, value);
			}
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<UserRemovableBuff>(), (AccessMode)0);
			if (!removableByPlayer && ((EntityManager)(ref entityManager)).HasComponent(buff, val))
			{
				((EntityManager)(ref entityManager)).RemoveComponent(buff, val);
			}
			if (Present<BuffCategory>(entityManager, buff))
			{
				BuffCategory value2 = Read<BuffCategory>(entityManager, buff);
				value2.Groups = (BuffCategoryFlag)0;
				Write<BuffCategory>(entityManager, buff, value2);
			}
			if (PresentWithElements<RemoveBuffOnGameplayEventEntry>(entityManager, buff))
			{
				RemoveBuffOnGameplayEventEntry value3 = ReadElement<RemoveBuffOnGameplayEventEntry>(entityManager, buff, 0);
				value3.BuffCategoryFlag = (BuffCategoryFlag)0;
				WriteElement<RemoveBuffOnGameplayEventEntry>(entityManager, buff, 0, value3);
			}
			ComponentType val2 = default(ComponentType);
			((ComponentType)(ref val2))..ctor(Il2CppType.Of<Buff_Persists_Through_Death>(), (AccessMode)0);
			if (!persistsThroughDeath && ((EntityManager)(ref entityManager)).HasComponent(buff, val2))
			{
				((EntityManager)(ref entityManager)).RemoveComponent(buff, val2);
			}
			if (!PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, buff))
			{
				return;
			}
			int num = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, buff);
			ModifyUnitStatBuff_DOTS val3 = ReadElement<ModifyUnitStatBuff_DOTS>(entityManager, buff, 0);
			for (int i = 0; i < stats.Length; i++)
			{
				ModifyUnitStatBuff_DOTS val4 = val3;
				val4.StatType = stats[i].Stat;
				val4.ModificationType = (ModificationType)3;
				val4.Value = stats[i].Value;
				val4.AttributeCapType = (AttributeCapType)(-1);
				if (i < num)
				{
					WriteElement<ModifyUnitStatBuff_DOTS>(entityManager, buff, i, val4);
					continue;
				}
				trace($"[{world.Name}] {name}: adding stat entry {i}");
				((EntityManager)(ref entityManager)).GetBuffer<ModifyUnitStatBuff_DOTS>(buff, false).Add(val4);
			}
		}

		public static List<string> Verify(World world)
		{
			//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)
			//IL_0015: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0054: 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_005f: 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_0072: 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_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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			EntityManager entityManager = world.EntityManager;
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			PrefabLookupMap prefabLookupMap = existingSystemManaged._PrefabLookupMap;
			int num = 0;
			BrewDefinition[] all = BrewCatalog.All;
			Entity entity = default(Entity);
			Entity entity2 = default(Entity);
			Entity entity3 = default(Entity);
			Entity val = default(Entity);
			PrefabGUID val2 = default(PrefabGUID);
			foreach (BrewDefinition brewDefinition in all)
			{
				List<string> list2 = new List<string>();
				bool num2 = existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.GroupGuid, ref entity) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.CastGuid, ref entity2) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.ActivateGuid, ref entity3) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.BuffGuid, ref val);
				Entity entity4 = Entity.Null;
				if (!(num2 & (((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val2, false) && existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val2, ref entity4))))
				{
					list2.Add("a prefab of the chain is missing");
				}
				else
				{
					if (Present<CastAbilityOnConsume>(entityManager, entity4))
					{
						CastAbilityOnConsume val3 = Read<CastAbilityOnConsume>(entityManager, entity4);
						if (((PrefabGUID)(ref val3.AbilityGuid)).GuidHash != ((PrefabGUID)(ref brewDefinition.GroupGuid)).GuidHash)
						{
							list2.Add("the item casts another ability");
						}
					}
					if (PresentWithElements<AbilityGroupStartAbilitiesBuffer>(entityManager, entity))
					{
						AbilityGroupStartAbilitiesBuffer val4 = ReadElement<AbilityGroupStartAbilitiesBuffer>(entityManager, entity, 0);
						if (((PrefabGUID)(ref val4.PrefabGUID)).GuidHash != ((PrefabGUID)(ref brewDefinition.CastGuid)).GuidHash)
						{
							list2.Add("the group starts another cast");
						}
					}
					if (Present<AbilityState>(entityManager, entity2))
					{
						AbilityState val5 = Read<AbilityState>(entityManager, entity2);
						if (((PrefabGUID)(ref val5.AbilityId)).GuidHash != ((PrefabGUID)(ref brewDefinition.CastGuid)).GuidHash)
						{
							list2.Add("the cast has another ability id");
						}
					}
					if (PresentWithElements<AbilitySpawnPrefabOnCast>(entityManager, entity2))
					{
						AbilitySpawnPrefabOnCast val6 = ReadElement<AbilitySpawnPrefabOnCast>(entityManager, entity2, 0);
						if (((PrefabGUID)(ref val6.SpawnPrefab)).GuidHash != ((PrefabGUID)(ref brewDefinition.ActivateGuid)).GuidHash)
						{
							list2.Add("the cast spawns another activation");
						}
					}
					if (PresentWithElements<ApplyBuffOnGameplayEvent>(entityManager, entity3))
					{
						ApplyBuffOnGameplayEvent val7 = ReadElement<ApplyBuffOnGameplayEvent>(entityManager, entity3, 0);
						if (((PrefabGUID)(ref val7.Buff0)).GuidHash != ((PrefabGUID)(ref brewDefinition.BuffGuid)).GuidHash)
						{
							list2.Add("the activation applies another buff");
						}
					}
					if (Present<LifeTime>(entityManager, val) && Read<LifeTime>(entityManager, val).Duration != brewDefinition.DurationSeconds)
					{
						list2.Add("the buff has another duration");
					}
					int num3 = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, val);
					if (PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, val))
					{
						if (num3 != brewDefinition.Stats.Length)
						{
							list2.Add($"the buff has {num3} stats, the brew {brewDefinition.Stats.Length}");
						}
						else
						{
							for (int j = 0; j < num3; j++)
							{
								ModifyUnitStatBuff_DOTS val8 = ReadElement<ModifyUnitStatBuff_DOTS>(entityManager, val, j);
								if (val8.StatType != brewDefinition.Stats[j].Stat || val8.Value != brewDefinition.Stats[j].Value)
								{
									list2.Add($"stat {j} is {val8.StatType} {val8.Value}");
								}
							}
						}
					}
					bool flag = ((EntityManager)(ref entityManager)).HasComponent(val, new ComponentType(Il2CppType.Of<Buff_Persists_Through_Death>(), (AccessMode)0));
					if (!CustomItemRegistry.IsClient && flag != brewDefinition.PersistsThroughDeath)
					{
						list2.Add($"persists through death: {flag}");
					}
				}
				if (list2.Count == 0)
				{
					num++;
				}
				else
				{
					list.Add("verify FAIL brew " + brewDefinition.Name + ": " + string.Join("; ", list2));
				}
			}
			int num4 = 0;
			SealDefinition[] all2 = SealCatalog.All;
			Entity val9 = default(Entity);
			foreach (SealDefinition sealDefinition in all2)
			{
				List<string> list3 = new List<string>();
				if (!existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(sealDefinition.BuffGuid, ref val9))
				{
					list3.Add("no prefab");
				}
				else
				{
					if (Present<LifeTime>(entityManager, val9) && (int)Read<LifeTime>(entityManager, val9).EndAction != 0)
					{
						list3.Add("the buff runs out");
					}
					if (((EntityManager)(ref entityManager)).HasComponent(val9, new ComponentType(Il2CppType.Of<UserRemovableBuff>(), (AccessMode)0)))
					{
						list3.Add("the player can take it off");
					}
					int num5 = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, val9);
					if (PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, val9) && num5 != sealDefinition.Stats.Length)
					{
						list3.Add($"the buff has {num5} stats, the seal {sealDefinition.Stats.Length}");
					}
				}
				if (list3.Count == 0)
				{
					num4++;
				}
				else
				{
					list.Add("verify FAIL seal " + sealDefinition.Name + ": " + string.Join("; ", list3));
				}
			}
			Entity entity5 = default(Entity);
			bool flag2 = existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(SealCatalog.SetBuffGuid, ref entity5);
			int value = (flag2 ? BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, entity5) : 0);
			list.Add($"verify summary: {num4}/{SealCatalog.All.Length} seals OK; set of all: " + (flag2 ? $"{value} stats, {SealCatalog.SetMultiplierText(polish: false)}" : "no prefab"));
			list.Add($"verify summary: {num}/{BrewCatalog.All.Length} brews OK" + ((LeftOut.Count > 0) ? ("; not on this side's prefabs: " + string.Join(", ", LeftOut)) : "") + ((Repointed.Count > 0) ? ("; repointed: " + string.Join(", ", Repointed)) : ""));
			return list;
		}

		public static List<string> RegisterClientData(World world, Action<string> trace)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Expected O, but got Unknown
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Expected O, but got Unknown
			List<string> list = new List<string>();
			PrefabLookupMap prefabLookupMap = world.GetExistingSystemManaged<PrefabCollectionSystem>()._PrefabLookupMap;
			ManagedDataRegistry managedDataRegistry = world.GetExistingSystemManaged<GameDataSystem>().ManagedDataRegistry;
			Dictionary<PrefabLookupKey, Object> dataLookupMap = managedDataRegistry._DataLookupMap;
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			PrefabGUID val = default(PrefabGUID);
			for (int i = 0; i < SourceNames.Length; i++)
			{
				if (((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(SourceNames[i], ref val, false))
				{
					dictionary[((PrefabGUID)(ref val)).GuidHash] = i;
				}
			}
			List<(int, Type, Object)> list2 = new List<(int, Type, Object)>();
			HashSet<(int, string)> hashSet = new HashSet<(int, string)>();
			Enumerator<PrefabLookupKey, Object> enumerator = dataLookupMap.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<PrefabLookupKey, Object> current = enumerator.Current;
				if (current.Value != null)
				{
					PrefabGUID prefabGUID = current.Key.PrefabGUID;
					int guidHash = ((PrefabGUID)(ref prefabGUID)).GuidHash;
					if (dictionary.TryGetValue(guidHash, out var value))
					{
						list2.Add((value, current.Key.ComponentType, current.Value));
					}
					else
					{
						hashSet.Add((guidHash, current.Key.ComponentType.FullName));
					}
				}
			}
			foreach (var item in list2)
			{
				list.Add($"brew interface data: {SourceNames[item.Item1]} has {((MemberInfo)item.Item3.GetIl2CppType()).Name} (as {((MemberInfo)item.Item2).Name})");
			}
			if (list2.Count == 0)
			{
				list.Add("brew interface data: the game keeps none for the source potion's ability and buff");
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			BrewDefinition[] all = BrewCatalog.All;
			PrefabGUID val2 = default(PrefabGUID);
			foreach (BrewDefinition brewDefinition in all)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val2, false))
				{
					continue;
				}
				ManagedItemData orDefaultWithoutLogging = managedDataRegistry.GetOrDefaultWithoutLogging<ManagedItemData>(val2, (ManagedItemData)null);
				PrefabGUID[] array = (PrefabGUID[])(object)new PrefabGUID[4] { brewDefinition.GroupGuid, brewDefinition.CastGuid, brewDefinition.ActivateGuid, brewDefinition.BuffGuid };
				foreach (var item2 in list2)
				{
					PrefabGUID prefabGUID2 = array[item2.Item1];
					if (hashSet.Contains((((PrefabGUID)(ref prefabGUID2)).GuidHash, item2.Item2.FullName)))
					{
						continue;
					}
					try
					{
						Object value2 = item2.Item3;
						if (orDefaultWithoutLogging != null && ((Il2CppObjectBase)item2.Item3).TryCast<ManagedItemData>() != null)
						{
							value2 = (Object)(object)orDefaultWithoutLogging;
							num++;
						}
						else if (orDefaultWithoutLogging != null && ((Il2CppObjectBase)item2.Item3).TryCast<ManagedAbilityGroupData>() != null)
						{
							value2 = (Object)new ManagedAbilityGroupData
							{
								Name = orDefaultWithoutLogging.Name,
								Description = orDefaultWithoutLogging.Description,
								Icon = orDefaultWithoutLogging.Icon
							};
							num++;
						}
						else
						{
							num2++;
						}
						trace($"[{world.Name}] {((MemberInfo)item2.Item3.GetIl2CppType()).Name} of {SourceNames[item2.Item1]} for {((PrefabGUID)(ref prefabGUID2)).GuidHash}");
						PrefabLookupKey boxedKey = new PrefabLookupKey
						{
							PrefabGUID = prefabGUID2,
							ComponentType = item2.Item2
						};
						Il2CppDictionary.AddWithUnboxedKey((Il2CppObjectBase)(object)dataLookupMap, (Il2CppObjectBase)(object)boxedKey, (Il2CppObjectBase)(object)value2);
					}
					catch (Exception ex)
					{
						num3++;
						list.Add($"brew interface data: entry for {((PrefabGUID)(ref prefabGUID2)).GuidHash} failed: {ex.Message}");
					}
				}
			}
			list.Add($"brew interface data: {num} entries with the brew's own name and icon, {num2} shared with the source, {num3} failed");
			if (BuffBarWriter != null)
			{
				list.Add(BuffBarWriter(world));
			}
			return list;
		}

		private unsafe static void SetGuid<T>(EntityManager entityManager, Entity entity, string field, PrefabGUID guid) where T : struct
		{
			//IL_000f: 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_0011: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* componentDataRawRW = (byte*)((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, val.TypeIndex);
			Unsafe.Write(componentDataRawRW + (int)Marshal.OffsetOf<T>(field), guid);
		}

		private unsafe static void SetGuidInBuffer<T>(EntityManager entityManager, Entity entity, string field, PrefabGUID guid) where T : struct
		{
			//IL_000f: 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_0011: 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_003f: 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_0058: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			if (((EntityManager)(ref entityManager)).GetBufferLength(entity, val.TypeIndex) == 0)
			{
				throw new InvalidOperationException(typeof(T).Name + " is empty on the prefab it is to be changed on");
			}
			byte* bufferRawRW = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRW(entity, val.TypeIndex);
			Unsafe.Write(bufferRawRW + (int)Marshal.OffsetOf<T>(field), guid);
		}

		private unsafe static T Read<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			return Marshal.PtrToStructure<T>(new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, val.TypeIndex)));
		}

		private unsafe static void Write<T>(EntityManager entityManager, Entity entity, T value) where T : struct
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			Marshal.StructureToPtr(value, new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, val.TypeIndex)), fDeleteOld: false);
		}

		private static int BufferLength<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_000f: 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_001c: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			if (!((EntityManager)(ref entityManager)).HasComponent(entity, val))
			{
				return 0;
			}
			return ((EntityManager)(ref entityManager)).GetBufferLength(entity, val.TypeIndex);
		}

		private unsafe static T ReadElement<T>(EntityManager entityManager, Entity entity, int index) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* bufferRawRO = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRO(entity, val.TypeIndex);
			return Marshal.PtrToStructure<T>(new IntPtr(bufferRawRO + index * Marshal.SizeOf<T>()));
		}

		private unsafe static void WriteElement<T>(EntityManager entityManager, Entity entity, int index, T value) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* bufferRawRW = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRW(entity, val.TypeIndex);
			Marshal.StructureToPtr(value, new IntPtr(bufferRawRW + index * Marshal.SizeOf<T>()), fDeleteOld: false);
		}
	}
	internal sealed class PrisonerFeedEffect
	{
		public float HealthMin;

		public float HealthMax;

		public float MiseryReliefMin;

		public float MiseryReliefMax;

		public float BloodQualityBonus;

		public bool BloodQualityStaysInTier;

		public float DrainHealthFactor = 1f;

		public bool FreezesMisery;

		public bool Lasts
		{
			get
			{
				if (!(DrainHealthFactor < 1f))
				{
					return FreezesMisery;
				}
				return true;
			}
		}
	}
	internal struct IconTint
	{
		public float Hue;

		public float Saturation;

		public IconTint(float hue, float saturation)
		{
			Hue = hue;
			Saturation = saturation;
		}
	}
	internal sealed class FishDescription
	{
		public readonly string SourceItem;

		public readonly string RarityWord;

		public readonly string RarityWordPl;

		public FishDescription(string sourceItem, string rarityWord, string rarityWordPl)
		{
			SourceItem = sourceItem;
			RarityWord = rarityWord;
			RarityWordPl = rarityWordPl;
		}
	}
	internal sealed class CustomItemDefinition
	{
		private const int NameKeyA = 1146179585;

		private const int NameKeyB = 1380207439;

		private const int NameKeyC = 1112493125;

		private const int DescriptionKeyC = 1112493126;

		public PrefabGUID Guid;

		public string PrefabName;

		public string DisplayName;

		public string DisplayNamePl;

		public string SourceItemName;

		public PrisonerFeedEffect Feed;

		public string IconName;

		public IconTint IconTint;

		public int IconMarks;

		public FishDescription Description;

		public BrewDefinition Brew;

		public Func<bool, string> OwnDescription;

		public float WeaponLevel;

		public AssetGuid NameKey => NameKeyOf(Guid);

		public AssetGuid DescriptionKey => DescriptionKeyOf(Guid);

		public static AssetGuid NameKeyOf(PrefabGUID guid)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new AssetGuid(1146179585, 1380207439, 1112493125, ((PrefabGUID)(ref guid)).GuidHash);
		}

		public static AssetGuid DescriptionKeyOf(PrefabGUID guid)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new AssetGuid(1146179585, 1380207439, 1112493126, ((PrefabGUID)(ref guid)).GuidHash);
		}
	}
	internal static class CustomItemCatalog
	{
		private const int FirstGuid = 1146179585;

		public const string FishPrefabPrefix = "Item_Ingredient_Fish_DeepRising_";

		public const string FeedPrefabPrefix = "FakeItem_FeedPrisoner_DeepRising_";

		private const string FishSource = "Item_Ingredient_Fish_FatGoby_T01";

		private const string FeedSource = "FakeItem_FeedPrisoner_FatGoby";

		private const string BrewIconPrefix = "Brew";

		private const string AccessorySource = "Item_Ingredient_FishBone";

		private const string AccessoryIconPrefix = "Accessory_";

		private const string RodIconPrefix = "Rod";

		private const int FirstRodTier = 2;

		private static readonly IconTint[] AccessoryTints = new IconTint[4]
		{
			new IconTint(0.12f, 0.35f),
			new IconTint(0.6f, 0.9f),
			new IconTint(0.07f, 1.1f),
			new IconTint(0.58f, 0.1f)
		};

		private static readonly IconTint[] RodTints = new IconTint[3]
		{
			new IconTint(0.58f, 0.45f),
			new IconTint(0.55f, 0.05f),
			new IconTint(0.98f, 1.2f)
		};

		private const int FishPerRarity = 4;

		private static readonly FishDescription[] DescriptionsByRarity = new FishDescription[3]
		{
			new FishDescription("Item_Ingredient_Fish_SageFish_T02", null, null),
			new FishDescription("Item_Ingredient_Fish_GoldenRiverBass_T03", null, null),
			new FishDescription("Item_Ingredient_Fish_GoldenRiverBass_T03", "legendary", "Legendarna")
		};

		private const float Full = 1f;

		private static readonly PrisonerFeedEffect UncommonFeed = Feed(0.4f, 0.6f, 0.1f, 0.2f);

		private static readonly PrisonerFeedEffect RareFeed = Feed(0.7f, 1f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect LegendaryFeed = Feed(1f, 1f, 1f, 1f);

		private static readonly PrisonerFeedEffect UncommonShadowFeed = Feed(0.4f, 0.6f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect RareShadowFeed = Feed(0.7f, 1f, 0.5f, 0.6f);

		private static readonly PrisonerFeedEffect UncommonSlaughterFeed = Feed(0.8f, 1f, 0.1f, 0.2f);

		private static readonly PrisonerFeedEffect RareSlaughterFeed = Feed(1f, 1f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect SturgeonFeed = Lasting(RareSlaughterFeed, 0.5f, freezesMisery: false);

		private static readonly PrisonerFeedEffect VoltfangFeed = Lasting(LegendaryFeed, 0f, freezesMisery: false);

		private static readonly PrisonerFeedEffect LeviathanFeed = Lasting(LegendaryFeed, 1f, freezesMisery: true);

		private static readonly PrisonerFeedEffect RareBloodFeed = Feed(0.7f, 1f, 0.25f, 0.35f, 1f, bloodQualityStaysInTier: true);

		private static readonly PrisonerFeedEffect LegendaryBloodFeed = Feed(1f, 1f, 1f, 1f, 5f);

		public static readonly CustomItemDefinition[] All = Build();

		public static CustomItemDefinition Find(PrefabGUID guid)
		{
			CustomItemDefinition[] all = All;
			foreach (CustomItemDefinition customItemDefinition in all)
			{
				if (((PrefabGUID)(ref customItemDefinition.Guid)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash)
				{
					return customItemDefinition;
				}
			}
			return null;
		}

		private static CustomItemDefinition[] Build()
		{
			(string, string, string, PrisonerFeedEffect, IconTint)[] array = new(string, string, string, PrisonerFeedEffect, IconTint)[12]
			{
				("AshgillPerch", "Ashgill Perch", "Okoń popielnoskrzeli", UncommonFeed, new IconTint(0.08f, 0.25f)),
				("VeinfinMinnow", "Veinfin Minnow", "Strzebla żyłopłetwa", UncommonFeed, new IconTint(0.95f, 0.7f)),
				("DuskscaleCarp", "Duskscale Carp", "Karp zmierzchołuski", UncommonShadowFeed, new IconTint(0.74f, 0.7f)),
				("IronjawChub", "Ironjaw Chub", "Kleń żelaznoszczęki", UncommonSlaughterFeed, new IconTint(0.6f, 0.2f)),
				("GravetoothPike", "Gravetooth Pike", "Szczupak grobozęby", RareFeed, new IconTint(0.38f, 0.55f)),
				("CrimsonEel", "Crimson Eel", "Karmazynowy węgorz", RareBloodFeed, new IconTint(0f, 1f)),
				("EclipseKoi", "Eclipse Koi", "Koi zaćmienia", RareShadowFeed, new IconTint(0.08f, 1.1f)),
				("StormgillSturgeon", "Stormgill Sturgeon", "Jesiotr burzoskrzeli", SturgeonFeed, new IconTint(0.64f, 1f)),
				("OldMossback", "Old Mossback", "Stary Mchogrzbiet", LegendaryFeed, new IconTint(0.27f, 1f)),
				("CrimsonMatriarch", "Crimson Matriarch", "Karmazynowa Matrona", LegendaryBloodFeed, new IconTint(0.93f, 1.3f)),
				("ArgentLeviathan", "Argent Leviathan", "Srebrny Lewiatan", LeviathanFeed, new IconTint(0.55f, 0.05f)),
				("Voltfang", "Voltfang", "Piorunokieł", VoltfangFeed, new IconTint(0.15f, 1.3f))
			};
			List<CustomItemDefinition> items = new List<CustomItemDefinition>();
			for (int i = 0; i < array.Length; i++)
			{
				(string, string, string, PrisonerFeedEffect, IconTint) tuple = array[i];
				Add("Item_Ingredient_Fish_DeepRising_", "Item_Ingredient_Fish_FatGoby_T01", tuple.Item1, tuple.Item2, tuple.Item3, null, tuple.Item5);
				items[items.Count - 1].Description = DescriptionsByRarity[i / 4];
			}
			(string, string, string, PrisonerFeedEffect, IconTint)[] array2 = array;
			for (int j = 0; j < array2.Length; j++)
			{
				(string, string, string, PrisonerFeedEffect, IconTint) tuple2 = array2[j];
				Add("FakeItem_FeedPrisoner_DeepRising_", "FakeItem_FeedPrisoner_FatGoby", tuple2.Item1, tuple2.Item2, tuple2.Item3, tuple2.Item4, tuple2.Item5);
			}
			BrewDefinition[] all = BrewCatalog.All;
			foreach (BrewDefinition brewDefinition in all)
			{
				Add("Item_Consumable_DeepRising_Brew_", "Item_Consumable_PhysicalPowerPotion_T01", brewDefinition.Name, brewDefinition.DisplayName, brewDefinition.DisplayNamePl, null, brewDefinition.IconTint);
				items[items.Count - 1].IconName = "Brew" + brewDefinition.Name;
				items[items.Count - 1].IconMarks = brewDefinition.Tier;
				items[items.Count - 1].Brew = brewDefinition;
			}
			for (int k = 0; k < AccessoryCatalog.All.Length; k++)
			{
				Accessory accessory = AccessoryCatalog.All[k];
				Add(string.Empty, "Item_Ingredient_FishBone", accessory.Item, accessory.Name, accessory.NamePl, null, AccessoryTints[k % AccessoryTints.Length]);
				CustomItemDefinition customItemDefinition = items[items.Count - 1];
				customItemDefinition.IconName = "Accessory_" + accessory.Id;
				customItemDefinition.OwnDescription = (bool polish) => (!polish) ? ("A rod accessory: " + accessory.Description + ". It works while you carry it and have chosen it in the bait window; one accessory at a time.") : ("Akcesorium do wędki: " + accessory.DescriptionPl + ". Działa, gdy masz je przy sobie i wybierzesz w oknie przynęt; naraz jedno akcesorium.");
			}
			RodItem[] all2 = RodCatalog.All;
			foreach (RodItem rod in all2)
			{
				Add(string.Empty, "Item_Weapon_FishingPole_T01", rod.Item, rod.Name, rod.NamePl, null, RodTints[(rod.Tier - 2) % RodTints.Length]);
				CustomItemDefinition customItemDefinition2 = items[items.Count - 1];
				customItemDefinition2.IconName = "Rod" + rod.Tier;
				customItemDefinition2.WeaponLevel = rod.WeaponLevel;
				customItemDefinition2.OwnDescription = (bool polish) => polish ? $"Wędka poziomu {rod.Tier}: +{rod.QualityPoints} do jakości połowu. Liczy się najlepsza wędka, jaką masz przy sobie." : $"A fishing pole of tier {rod.Tier}: +{rod.QualityPoints} catch quality. The best pole you have with you is the one that counts.";
			}
			return items.ToArray();
			void Add(string prefix, string source, string name, string displayName, string displayNamePl, PrisonerFeedEffect feed, IconTint tint)
			{
				//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)
				items.Add(new CustomItemDefinition
				{
					Guid = new PrefabGUID(1146179585 + items.Count),
					PrefabName = prefix + name,
					DisplayName = displayName,
					DisplayNamePl = displayNamePl,
					SourceItemName = source,
					Feed = feed,
					IconName = name,
					IconTint = tint
				});
			}
		}

		private static PrisonerFeedEffect Lasting(PrisonerFeedEffect feed, float drainHealthFactor, bool freezesMisery)
		{
			return new PrisonerFeedEffect
			{
				HealthMin = feed.HealthMin,
				HealthMax = feed.HealthMax,
				MiseryReliefMin = feed.MiseryReliefMin,
				MiseryReliefMax = feed.MiseryReliefMax,
				BloodQualityBonus = feed.BloodQualityBonus,
				BloodQualityStaysInTier = feed.BloodQualityStaysInTier,
				DrainHealthFactor = drainHealthFactor,
				FreezesMisery = freezesMisery
			};
		}

		private static PrisonerFeedEffect Feed(float healthMin, float healthMax, float miseryReliefMin, float miseryReliefMax, float bloodQualityBonus = 0f, bool bloodQualityStaysInTier = false)
		{
			return new PrisonerFeedEffect
			{
				HealthMin = healthMin,
				HealthMax = healthMax,
				MiseryReliefMin = miseryReliefMin,
				MiseryReliefMax = miseryReliefMax,
				BloodQualityBonus = bloodQualityBonus,
				BloodQualityStaysInTier = bloodQualityStaysInTier
			};
		}
	}
	internal static class CustomItemRegistry
	{
		private sealed class WorldProgress
		{
			public bool PrefabsRegistered;

			public bool RecipesRegistered;

			public bool BrewsRegistered;

			public bool BrewDataRegistered;

			public bool BrewsFailed;

			public string LastBrewWaitReason;

			public bool TableExtended;

			public bool NamesRegistered;

			public bool Failed;

			public string LastWaitReason;

			public bool Complete
			{
				get
				{
					if (PrefabsRegistered && RecipesRegistered && TableExtended)
					{
						return NamesRegistered;
					}
					return false;
				}
			}
		}

		[HarmonyPatch(typeof(PrefabCollectionSystem), "OnUpdate")]
		private static class PrefabSystemPatch
		{
			private static void Prefix(PrefabCollectionSystem __instance)
			{
				Pump(((ComponentSystemBase)__instance).World);
			}
		}

		public const int KnownVanillaItemCount = 1083;

		private const string PolishLanguage = "polish";

		private const string EnglishLanguage = "english";

		private const string FeedDescriptionSourceItem = "FakeItem_FeedPrisoner_GoldenRiverBass";

		private const float PercentPerUnit = 100f;

		private const string BloodChangeBuffSourceItem = "FakeItem_FeedPrisoner_Corrupted";

		private const string HighlightOpen = "<color=#82C9D9>";

		private const string HighlightClose = "</color>";

		public static bool IsClient;

		public static Action<string> Log = delegate
		{
		};

		public static Func<CustomItemDefinition, Sprite, Sprite> IconProvider;

		public static Action<string> TraceSink;

		private static readonly Dictionary<ulong, WorldProgress> Worlds = new Dictionary<ulong, WorldProgress>();

		private static readonly HashSet<ulong> ServerHasMod = new HashSet<ulong>();

		private static readonly HashSet<int> InTable = new HashSet<int>();

		public static void ServerAnnouncedMod(World world)
		{
			ServerHasMod.Add(world.SequenceNumber);
		}

		public static bool ArePrefabsRegistered(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value) && value.PrefabsRegistered && value.RecipesRegistered)
			{
				if (!value.BrewsRegistered)
				{
					return value.BrewsFailed;
				}
				return true;
			}
			return false;
		}

		public static bool IsReadyForBuffs(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value) && value.Complete)
			{
				if (!value.BrewsRegistered)
				{
					return value.BrewsFailed;
				}
				return true;
			}
			return false;
		}

		public static bool IsComplete(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value))
			{
				return value.Complete;
			}
			return false;
		}

		public static void Pump(World world)
		{
			if (!HasPrefabSystems(world))
			{
				return;
			}
			if (!Worlds.TryGetValue(world.SequenceNumber, out var value))
			{
				value = (Worlds[world.SequenceNumber] = new WorldProgress());
			}
			if (value.Failed)
			{
				return;
			}
			bool flag = !IsClient || ServerHasMod.Contains(world.SequenceNumber);
			try
			{
				long started = FrameTimings.Start();
				foreach (string item in PrefabCloner.Audit(world))
				{
					Report(world, "prefab audit: " + item);
				}
				FrameTimings.Stop("items: audit", started);
				if (value.Complete)
				{
					started = FrameTimings.Start();
					PumpBrews(world, value);
					FrameTimings.Stop("items: brews", started);
					started = FrameTimings.Start();
					MaintainItemTable(world, value);
					FrameTimings.Stop("items: table", started);
					return;
				}
				if (!value.PrefabsRegistered)
				{
					if (!TryRegisterPrefabs(world))
					{
						return;
					}
					value.PrefabsRegistered = true;
					Report(world, $"{CustomItemCatalog.All.Length} custom item prefabs registered");
				}
				PumpBrews(world, value);
				if (!flag)
				{
					return;
				}
				if (!value.RecipesRegistered)
				{
					if (!CustomRecipeRegistry.TryRegisterPrefabs(world, Trace))
					{
						return;
					}
					value.RecipesRegistered = true;
					Report(world, $"{CustomRecipeCatalog.All.Length} custom recipe prefabs registered");
				}
				if (!value.TableExtended)
				{
					string text = TryExtendItemTable(world);
					if (text != null)
					{
						if (text != value.LastWaitReason)
						{
							Report(world, "item table not extended yet: " + text);
						}
						value.LastWaitReason = text;
						return;
					}
					value.TableExtended = true;
				}
				if (!value.NamesRegistered)
				{
					if (IsClient && !TryRegisterNames(world))
					{
						return;
					}
					value.NamesRegistered = true;
				}
				PumpBrews(world, value);
				if (IsClient)
				{
					RegisterTechNames(world);
				}
				AddRecipesToStations(world);
				foreach (string item2 in Verify(world))
				{
					Report(world, item2);
				}
				foreach (string item3 in CustomRecipeRegistry.Verify(world))
				{
					Report(world, item3);
				}
			}
			catch (Exception value2)
			{
				value.Failed = true;
				Report(world, $"FAILED, giving up in this world: {value2}");
			}
		}

		private static bool HasPrefabSystems(World world)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			if (world == null || !world.IsCreated)
			{
				return false;
			}
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			if (existingSystemManaged != null && world.GetExistingSystemManaged<GameDataSystem>() != null && existingSystemManaged._PrefabGuidToEntityMap.IsCreated)
			{
				return existingSystemManaged._PrefabDataLookup.IsCreated;
			}
			return false;
		}

		public static void SetGearBalance(GearBalance balance, World world)
		{
			GearBalance.Current = balance;
			BrewCatalog.Refresh();
			SealCatalog.Refresh();
			CustomRecipeCatalog.Refresh();
			if (world != null && Worlds.TryGetValue(world.SequenceNumber, out var value) && value.BrewsRegistered)
			{
				value.BrewsRegistered = false;
				Report(world, "the server's values differ from those the brews were built with; building them again");
			}
		}

		private static void PumpBrews(World world, WorldProgress progress)
		{
			if (progress.BrewsFailed)
			{
				return;
			}
			try
			{
				PumpBrewStages(world, progress);
			}
			catch (Exception value)
			{
				progress.BrewsFailed = true;
				Report(world, $"brews FAILED, giving up on them in this world: {value}");
			}
		}

		private static void RegisterTechNames(World world)
		{
			try
			{
				foreach (string item in CustomRecipeRegistry.RegisterTechNames(world, IsPolish()))
				{
					Report(world, item);
				}
			}
			catch (Exception value)
			{
				Report(world, $"tech names FAILED: {value}");
			}
		}

		private static void PumpBrewStages(World world, WorldProgress progress)
		{
			if (!progress.BrewsRegistered)
			{
				string text = CustomBrewRegistry.TryRegisterPrefabs(world, Trace);
				if (text != null)
				{
					if (text != progress.LastBrewWaitReason)
					{
						Report(world, "brews not registered yet: " + text);
					}
					progress.LastBrewWaitReason = text;
					return;
				}
				progress.BrewsRegistered = true;
				Report(world, $"{BrewCat

plugins/DeepRising/DeepRising.Server.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DeepRising.CustomItems;
using DeepRising.Probe;
using DeepRising.Server.Commands;
using DeepRising.Server.Fishing;
using DeepRising.Server.Prison;
using DeepRising.Server.Probe;
using DeepRising.Shared;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Gameplay.Scripting;
using ProjectM.Gameplay.Systems;
using ProjectM.Network;
using ProjectM.Scripting;
using ProjectM.Shared;
using ProjectM.Terrain;
using ProjectM.Tiles;
using ProjectM.UI;
using Stunlock.Core;
using Stunlock.Localization;
using Stunlock.Network;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DeepRising.Server")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+60570d036cb645189aa435c34b42d7162430cee3")]
[assembly: AssemblyProduct("DeepRising.Server")]
[assembly: AssemblyTitle("DeepRising.Server")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[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]
	[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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DeepRising.Probe
{
	internal static class FrameTimings
	{
		private sealed class Part
		{
			public long Calls;

			public long Ticks;

			public long MaxTicks;

			public long FrameTicks;
		}

		private const double SlowModMilliseconds = 3.0;

		private const double SlowFrameMilliseconds = 50.0;

		private const double SummarySeconds = 60.0;

		private const int MaxSlowFramesPerSummary = 20;

		private static readonly double TicksPerMillisecond = (double)Stopwatch.Frequency / 1000.0;

		private static readonly Dictionary<string, Part> Parts = new Dictionary<string, Part>();

		private static long _frameStart;

		private static long _summaryStart;

		private static int _slowFrames;

		private static int _frames;

		private static long _longestFrame;

		public static bool Enabled;

		public static Action<string> Log = delegate
		{
		};

		public static long Start()
		{
			if (!Enabled)
			{
				return 0L;
			}
			return Stopwatch.GetTimestamp();
		}

		public static void Stop(string name, long started)
		{
			if (Enabled && started != 0L)
			{
				long num = Stopwatch.GetTimestamp() - started;
				if (!Parts.TryGetValue(name, out var value))
				{
					value = (Parts[name] = new Part());
				}
				value.Calls++;
				value.Ticks += num;
				value.FrameTicks += num;
				if (num > value.MaxTicks)
				{
					value.MaxTicks = num;
				}
			}
		}

		public static void EndFrame(string side)
		{
			if (!Enabled)
			{
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			if (_summaryStart == 0L)
			{
				_summaryStart = timestamp;
			}
			long num = ((_frameStart == 0L) ? 0 : (timestamp - _frameStart));
			_frameStart = timestamp;
			_frames++;
			if (num > _longestFrame)
			{
				_longestFrame = num;
			}
			long num2 = 0L;
			foreach (Part value in Parts.Values)
			{
				num2 += value.FrameTicks;
			}
			bool flag = (double)num2 / TicksPerMillisecond >= 3.0;
			bool flag2 = (double)num / TicksPerMillisecond >= 50.0;
			if ((flag || flag2) && _slowFrames++ < 20)
			{
				StringBuilder stringBuilder = new StringBuilder($"[timings {side}] {(flag ? "slow mod" : "long frame")}: frame {(double)num / TicksPerMillisecond:F1} ms, the mod's {(double)num2 / TicksPerMillisecond:F2} ms");
				foreach (KeyValuePair<string, Part> part in Parts)
				{
					if ((double)part.Value.FrameTicks / TicksPerMillisecond >= 0.1)
					{
						StringBuilder stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder3 = stringBuilder2;
						StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2);
						handler.AppendLiteral(", ");
						handler.AppendFormatted(part.Key);
						handler.AppendLiteral(" ");
						handler.AppendFormatted((double)part.Value.FrameTicks / TicksPerMillisecond, "F2");
						stringBuilder3.Append(ref handler);
					}
				}
				Log(stringBuilder.ToString());
			}
			foreach (Part value2 in Parts.Values)
			{
				value2.FrameTicks = 0L;
			}
			if ((double)(timestamp - _summaryStart) / (double)Stopwatch.Frequency < 60.0)
			{
				return;
			}
			StringBuilder stringBuilder4 = new StringBuilder($"[timings {side}] {_frames} frames in {(double)(timestamp - _summaryStart) / (double)Stopwatch.Frequency:F0} s, longest {(double)_longestFrame / TicksPerMillisecond:F1} ms, {_slowFrames} slow;");
			foreach (KeyValuePair<string, Part> part2 in Parts)
			{
				StringBuilder stringBuilder2 = stringBuilder4;
				StringBuilder stringBuilder5 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(18, 4, stringBuilder2);
				handler.AppendLiteral(" ");
				handler.AppendFormatted(part2.Key);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(part2.Value.Calls);
				handler.AppendLiteral("x avg ");
				handler.AppendFormatted((double)part2.Value.Ticks / TicksPerMillisecond / (double)Math.Max(1L, part2.Value.Calls), "F3");
				handler.AppendLiteral(" max ");
				handler.AppendFormatted((double)part2.Value.MaxTicks / TicksPerMillisecond, "F2");
				handler.AppendLiteral(" ms;");
				stringBuilder5.Append(ref handler);
			}
			Log(stringBuilder4.ToString());
			Parts.Clear();
			_summaryStart = timestamp;
			_frames = 0;
			_slowFrames = 0;
			_longestFrame = 0L;
		}
	}
	internal static class InventoryProbe
	{
		private const int MaxSlotLines = 60;

		private const uint FnvOffsetBasis = 2166136261u;

		private const uint FnvPrime = 16777619u;

		public unsafe static List<string> DescribeCustomItems(World world)
		{
			//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)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			EntityManager entityManager = world.EntityManager;
			GameDataSystem existingSystemManaged = world.GetExistingSystemManaged<GameDataSystem>();
			PrefabGUID[] array = NativeItemTable.Read(world);
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			if (array == null)
			{
				list.Add("item table: none in this world");
			}
			else
			{
				uint num = 2166136261u;
				for (int i = 0; i < array.Length; i++)
				{
					dictionary[((PrefabGUID)(ref array[i])).GuidHash] = i;
					num = (num ^ (uint)((PrefabGUID)(ref array[i])).GuidHash) * 16777619;
				}
				bool value = true;
				for (int j = 1; j < array.Length; j++)
				{
					if (((PrefabGUID)(ref array[j - 1])).GuidHash > ((PrefabGUID)(ref array[j])).GuidHash)
					{
						value = false;
					}
				}
				list.Add($"item table: {array.Length} items, order hash {num:X8}, sorted by guid: {value}");
			}
			ComponentType val = ComponentType.ReadOnly(Il2CppType.Of<InventoryBuffer>());
			int num2 = Marshal.SizeOf<InventoryBuffer>();
			EntityQueryBuilder val2 = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
			val2 = ((EntityQueryBuilder)(ref val2)).AddAll(val);
			EntityQueryBuilder val3 = ((EntityQueryBuilder)(ref val2)).WithOptions((EntityQueryOptions)2);
			EntityQuery val4 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val3);
			((EntityQueryBuilder)(ref val3)).Dispose();
			NativeArray<Entity> val5 = ((EntityQuery)(ref val4)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
			try
			{
				int num3 = 0;
				int num4 = 0;
				Enumerator<Entity> enumerator = val5.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Entity current = enumerator.Current;
					int bufferLength = ((EntityManager)(ref entityManager)).GetBufferLength(current, val.TypeIndex);
					byte* bufferRawRO = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRO(current, val.TypeIndex);
					for (int k = 0; k < bufferLength; k++)
					{
						InventoryBuffer val6 = Marshal.PtrToStructure<InventoryBuffer>(new IntPtr(bufferRawRO + k * num2));
						CustomItemDefinition customItemDefinition = CustomItemCatalog.Find(val6.ItemType);
						if (customItemDefinition != null)
						{
							num3++;
							num4 += val6.Amount;
							if (num3 <= 60)
							{
								int value3;
								string value2 = (dictionary.TryGetValue(((PrefabGUID)(ref val6.ItemType)).GuidHash, out value3) ? value3.ToString() : "none");
								list.Add($"inventory {current.Index} slot {k}: {customItemDefinition.PrefabName} x{val6.Amount}, table index {value2}{DescribeUiName(existingSystemManaged, val6.ItemType)}");
							}
						}
					}
				}
				list.Add($"{num3} slots hold {num4} custom items in {val5.Length} inventories");
				return list;
			}
			finally
			{
				val5.Dispose();
				((EntityQuery)(ref val4)).Dispose();
			}
		}

		private static string DescribeUiName(GameDataSystem gameData, PrefabGUID guid)
		{
			//IL_0014: 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)
			if (!CustomItemRegistry.IsClient)
			{
				return "";
			}
			try
			{
				ManagedItemData orDefaultWithoutLogging = gameData.ManagedDataRegistry.GetOrDefaultWithoutLogging<ManagedItemData>(guid, (ManagedItemData)null);
				return (orDefaultWithoutLogging == null) ? ", UI name: NONE" : $", UI name '{Localization.Get(orDefaultWithoutLogging.Name, false)}', icon {(Object)(object)orDefaultWithoutLogging.Icon != (Object)null}";
			}
			catch (Exception ex)
			{
				return ", UI name check failed: " + ex.GetType().Name;
			}
		}
	}
}
namespace DeepRising.CustomItems
{
	internal struct BrewStat
	{
		public UnitStatType Stat;

		public float Value;

		public BrewStatUnit Unit;

		public BrewStat(UnitStatType stat, float value, BrewStatUnit unit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Stat = stat;
			Value = value;
			Unit = unit;
		}
	}
	internal enum BrewStatUnit
	{
		Percent,
		Points,
		Immunity
	}
	internal enum BrewFamily
	{
		Hunt,
		Blood,
		Shadow,
		Slaughter
	}
	internal sealed class BrewDefinition
	{
		public string Name;

		public BrewFamily Family;

		public int Tier;

		public string DisplayName;

		public string DisplayNamePl;

		public string Fish;

		public string EssenceItem;

		public int EssenceAmount;

		public float DurationSeconds;

		public bool PersistsThroughDeath;

		public string UnlockTech;

		public BrewStat[] Stats;

		public IconTint IconTint;

		public PrefabGUID GroupGuid;

		public PrefabGUID CastGuid;

		public PrefabGUID ActivateGuid;

		public PrefabGUID BuffGuid;

		public string ItemPrefabName => "Item_Consumable_DeepRising_Brew_" + Name;

		public string GroupPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_AbilityGroup";

		public string CastPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Cast";

		public string ActivatePrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Activate";

		public string BuffPrefabName => "AB_Consumable_DeepRising_Brew_" + Name + "_Buff";
	}
	internal static class BrewCatalog
	{
		private const int FirstGuid = 1146181585;

		private const int PrefabsPerBrew = 4;

		public const string ItemPrefabPrefix = "Item_Consumable_DeepRising_Brew_";

		public const string AbilityPrefabPrefix = "AB_Consumable_DeepRising_Brew_";

		public const string SourceItem = "Item_Consumable_PhysicalPowerPotion_T01";

		public const string SourceGroup = "AB_Consumable_PhysicalPowerPotion_T01_AbilityGroup";

		public const string SourceCast = "AB_Consumable_PhysicalPowerPotion_T01_Cast";

		public const string SourceActivate = "AB_Consumable_PhysicalPowerPotion_T01_Activate";

		public const string SourceBuff = "AB_Consumable_PhysicalPowerPotion_T01_Buff";

		private const string BloodEssence = "Item_BloodEssence_T01";

		private const int TierCount = 3;

		private const float SecondsPerMinute = 60f;

		private static readonly string[] TierNumerals = new string[3] { "I", "II", "III" };

		public static readonly (int Tier, VBloodTeacher Teacher)[] Teachers = new(int, VBloodTeacher)[3]
		{
			(1, VBloodTeachers.Finn),
			(2, VBloodTeachers.Raziel),
			(3, VBloodTeachers.Henry)
		};

		private const int PersistingTier = 3;

		private const float GarlicImmunity = 1000f;

		private static readonly List<(BrewDefinition Brew, Func<int, BrewStat[]> StatsOfTier)> Makers = new List<(BrewDefinition, Func<int, BrewStat[]>)>();

		public static readonly BrewDefinition[] All = Build();

		private const float PercentPerUnit = 100f;

		private const string HighlightOpen = "<color=#82C9D9>";

		private const string HighlightClose = "</color>";

		private static GearBalance Values => GearBalance.Current;

		public static string TierNumeral(int tier)
		{
			return TierNumerals[tier - 1];
		}

		public static BrewDefinition FindByItem(string itemPrefabName)
		{
			BrewDefinition[] all = All;
			foreach (BrewDefinition brewDefinition in all)
			{
				if (brewDefinition.ItemPrefabName == itemPrefabName)
				{
					return brewDefinition;
				}
			}
			return null;
		}

		public static BrewDefinition FirstOfTier(int tier)
		{
			BrewDefinition[] all = All;
			foreach (BrewDefinition brewDefinition in all)
			{
				if (brewDefinition.Tier == tier)
				{
					return brewDefinition;
				}
			}
			return null;
		}

		public static bool IsBrewBuff(PrefabGUID guid)
		{
			BrewDefinition[] all = All;
			for (int i = 0; i < all.Length; i++)
			{
				if (((PrefabGUID)(ref all[i].BuffGuid)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash)
				{
					return true;
				}
			}
			return false;
		}

		private static BrewDefinition[] Build()
		{
			List<BrewDefinition> brews = new List<BrewDefinition>();
			AddFamily(BrewFamily.Hunt, "Hunt", "Brew of the Hunt", "Wywar Łowów", 0.27f, new string[3] { "AshgillPerch", "GravetoothPike", "OldMossback" }, (int tier) => new BrewStat[1]
			{
				new BrewStat((UnitStatType)3, Values.BrewYieldBonus[tier], BrewStatUnit.Percent)
			});
			AddFamily(BrewFamily.Blood, "Blood", "Brew of Blood", "Wywar Krwi", 0.98f, new string[3] { "VeinfinMinnow", "CrimsonEel", "CrimsonMatriarch" }, (int tier) => new BrewStat[1]
			{
				new BrewStat((UnitStatType)81, Values.BrewBloodDrainReduction[tier], BrewStatUnit.Percent)
			});
			AddFamily(BrewFamily.Shadow, "Shadow", "Brew of Shadow", "Wywar Cienia", 0.74f, new string[3] { "DuskscaleCarp", "EclipseKoi", "ArgentLeviathan" }, (int tier) => new BrewStat[3]
			{
				Resistance((UnitStatType)19, Values.BrewSunResistance[tier]),
				Resistance((UnitStatType)10, Values.BrewHolyResistance[tier]),
				Resistance((UnitStatType)20, Values.BrewGarlicResistance[tier])
			});
			AddFamily(BrewFamily.Slaughter, "Slaughter", "Brew of Slaughter", "Wywar Mordu", 0.6f, new string[3] { "IronjawChub", "StormgillSturgeon", "Voltfang" }, (int tier) => new BrewStat[2]
			{
				new BrewStat((UnitStatType)67, Values.BrewPowerBonus[tier], BrewStatUnit.Percent),
				new BrewStat((UnitStatType)68, Values.BrewPowerBonus[tier], BrewStatUnit.Percent)
			});
			return brews.ToArray();
			void AddFamily(BrewFamily family, string name, string displayName, string displayNamePl, float hue, string[] fish, Func<int, BrewStat[]> statsOfTier)
			{
				//IL_00be: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < 3; i++)
				{
					int num = 1146181585 + brews.Count * 4;
					BrewDefinition brewDefinition = new BrewDefinition
					{
						Name = name + (i + 1),
						Family = family,
						Tier = i + 1,
						DisplayName = displayName + " " + TierNumerals[i],
						DisplayNamePl = displayNamePl + " " + TierNumerals[i],
						Fish = fish[i],
						EssenceItem = "Item_BloodEssence_T01",
						PersistsThroughDeath = (i + 1 >= 3),
						UnlockTech = CustomTechCatalog.BrewTechName(i + 1),
						IconTint = new IconTint(hue, 1f),
						GroupGuid = new PrefabGUID(num),
						CastGuid = new PrefabGUID(num + 1),
						ActivateGuid = new PrefabGUID(num + 2),
						BuffGuid = new PrefabGUID(num + 3)
					};
					brews.Add(brewDefinition);
					Makers.Add((brewDefinition, statsOfTier));
					Fill(brewDefinition, statsOfTier);
				}
			}
		}

		private static BrewStat Resistance(UnitStatType stat, float points)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new BrewStat(stat, points, (!(points >= 1000f)) ? BrewStatUnit.Points : BrewStatUnit.Immunity);
		}

		private static void Fill(BrewDefinition brew, Func<int, BrewStat[]> statsOfTier)
		{
			int num = brew.Tier - 1;
			brew.EssenceAmount = Math.Max(1, (int)Math.Round(Values.BrewEssenceAmount[num]));
			brew.DurationSeconds = Values.BrewDurationMinutes[num] * 60f;
			brew.Stats = statsOfTier(num);
		}

		public static void Refresh()
		{
			_ = All;
			foreach (var maker in Makers)
			{
				Fill(maker.Brew, maker.StatsOfTier);
			}
		}

		public static string DescriptionOf(BrewDefinition brew, bool polish)
		{
			List<string> list = new List<string>();
			BrewStat[] stats = brew.Stats;
			foreach (BrewStat stat in stats)
			{
				list.Add(EffectText(stat, polish));
			}
			string value = $"{"<color=#82C9D9>"}{brew.DurationSeconds / 60f:0}{"</color>"}";
			if (polish)
			{
				return $"Wywar z ryby i esencji krwi. {string.Join(", ", list)} przez {value} min." + (brew.PersistsThroughDeath ? " Działa dalej po śmierci." : " Kończy się wraz ze śmiercią.") + " Naraz działa tylko jeden wywar.";
			}
			return $"A brew of fish and blood essence. {string.Join(", ", list)} for {value} minutes." + (brew.PersistsThroughDeath ? " It lasts through death." : " It ends with death.") + " Only one brew is active at a time.";
		}

		private static string EffectText(BrewStat stat, bool polish)
		{
			return EffectText(stat, polish, highlighted: true);
		}

		public static string Highlight(string text)
		{
			return "<color=#82C9D9>" + text + "</color>";
		}

		public static string EffectText(BrewStat stat, bool polish, bool highlighted)
		{
			//IL_0021: 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_004b: Invalid comparison between Unknown and I4
			string value = (highlighted ? "<color=#82C9D9>" : string.Empty);
			string value2 = (highlighted ? "</color>" : string.Empty);
			string value3 = StatName(stat.Stat, polish);
			switch (stat.Unit)
			{
			case BrewStatUnit.Percent:
			{
				string value4 = (((int)stat.Stat == 81) ? "-" : "+");
				return $"{value3} {value}{value4}{stat.Value * 100f:0.#}%{value2}";
			}
			case BrewStatUnit.Immunity:
				return $"{value3}: {value}{(polish ? "niewrażliwość" : "immunity")}{value2}";
			default:
				return $"{value3} {value}+{stat.Value:0}{value2}";
			}
		}

		private unsafe static string StatName(UnitStatType stat, bool polish)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			if ((int)stat <= 19)
			{
				if ((int)stat <= 10)
				{
					if ((int)stat == 3)
					{
						if (!polish)
						{
							return "Resource yield";
						}
						return "Zbiór surowców";
					}
					if ((int)stat == 10)
					{
						if (!polish)
						{
							return "Holy resistance";
						}
						return "Odporność na świętość";
					}
				}
				else
				{
					if ((int)stat == 11)
					{
						if (!polish)
						{
							return "Silver resistance";
						}
						return "Odporność na srebro";
					}
					if ((int)stat == 19)
					{
						if (!polish)
						{
							return "Sun resistance";
						}
						return "Odporność na słońce";
					}
				}
			}
			else if ((int)stat <= 67)
			{
				if ((int)stat == 20)
				{
					if (!polish)
					{
						return "Garlic resistance";
					}
					return "Odporność na czosnek";
				}
				if ((int)stat == 67)
				{
					if (!polish)
					{
						return "Physical power";
					}
					return "Moc fizyczna";
				}
			}
			else
			{
				if ((int)stat == 68)
				{
					if (!polish)
					{
						return "Spell power";
					}
					return "Moc zaklęć";
				}
				if ((int)stat == 81)
				{
					if (!polish)
					{
						return "Blood drain";
					}
					return "Zużycie krwi";
				}
			}
			return ((object)(*(UnitStatType*)(&stat))/*cast due to .constrained prefix*/).ToString();
		}
	}
	internal static class CustomBrewRegistry
	{
		private const DropTriggerType NoDropTrigger = (DropTriggerType)7;

		private static readonly string[] SourceNames = new string[4] { "AB_Consumable_PhysicalPowerPotion_T01_AbilityGroup", "AB_Consumable_PhysicalPowerPotion_T01_Cast", "AB_Consumable_PhysicalPowerPotion_T01_Activate", "AB_Consumable_PhysicalPowerPotion_T01_Buff" };

		public static readonly SortedSet<string> Repointed = new SortedSet<string>();

		public static readonly SortedSet<string> LeftOut = new SortedSet<string>();

		public const float Forever = 0f;

		public static Func<World, string> BuffBarWriter;

		public static string TryRegisterPrefabs(World world, Action<string> trace)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = world.EntityManager;
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			PrefabLookupMap prefabLookupMap = existingSystemManaged._PrefabLookupMap;
			Entity[] array = (Entity[])(object)new Entity[SourceNames.Length];
			PrefabGUID[] array2 = (PrefabGUID[])(object)new PrefabGUID[SourceNames.Length];
			for (int i = 0; i < SourceNames.Length; i++)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(SourceNames[i], ref array2[i], false))
				{
					return "the game has no prefab " + SourceNames[i];
				}
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetValueWithoutLogging(array2[i], ref array[i]))
				{
					return SourceNames[i] + " has no entity yet";
				}
			}
			BrewDefinition[] all = BrewCatalog.All;
			PrefabGUID val = default(PrefabGUID);
			Entity val2 = default(Entity);
			foreach (BrewDefinition brewDefinition in all)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val, false) || !existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val, ref val2))
				{
					return "the item " + brewDefinition.ItemPrefabName + " is not registered";
				}
			}
			all = BrewCatalog.All;
			PrefabGUID val7 = default(PrefabGUID);
			Entity val8 = default(Entity);
			Entity val9 = default(Entity);
			foreach (BrewDefinition brewDefinition2 in all)
			{
				trace("[" + world.Name + "] building the brew " + brewDefinition2.Name);
				Entity val3 = CloneOnce(world, existingSystemManaged, array[0], array2[0], brewDefinition2.GroupGuid, brewDefinition2.GroupPrefabName);
				Entity val4 = CloneOnce(world, existingSystemManaged, array[1], array2[1], brewDefinition2.CastGuid, brewDefinition2.CastPrefabName);
				Entity val5 = CloneOnce(world, existingSystemManaged, array[2], array2[2], brewDefinition2.ActivateGuid, brewDefinition2.ActivatePrefabName);
				Entity val6 = CloneOnce(world, existingSystemManaged, array[3], array2[3], brewDefinition2.BuffGuid, brewDefinition2.BuffPrefabName);
				((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition2.ItemPrefabName, ref val7, false);
				existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val7, ref val8);
				if (Present<CastAbilityOnConsume>(entityManager, val8))
				{
					SetGuid<CastAbilityOnConsume>(entityManager, val8, "AbilityGuid", brewDefinition2.GroupGuid);
				}
				if (PresentWithElements<AbilityGroupStartAbilitiesBuffer>(entityManager, val3))
				{
					SetGuidInBuffer<AbilityGroupStartAbilitiesBuffer>(entityManager, val3, "PrefabGUID", brewDefinition2.CastGuid);
				}
				if (Present<AbilityState>(entityManager, val4))
				{
					SetGuid<AbilityState>(entityManager, val4, "AbilityId", brewDefinition2.CastGuid);
				}
				if (PresentWithElements<AbilitySpawnPrefabOnCast>(entityManager, val4))
				{
					SetGuidInBuffer<AbilitySpawnPrefabOnCast>(entityManager, val4, "SpawnPrefab", brewDefinition2.ActivateGuid);
				}
				if (PresentWithElements<ApplyBuffOnGameplayEvent>(entityManager, val5))
				{
					SetGuidInBuffer<ApplyBuffOnGameplayEvent>(entityManager, val5, "Buff0", brewDefinition2.BuffGuid);
				}
				if (PresentWithElements<DropFromTablesOnGameplayEvent>(entityManager, val5))
				{
					DropFromTablesOnGameplayEvent value = ReadElement<DropFromTablesOnGameplayEvent>(entityManager, val5, 0);
					value.DropTrigger = (DropTriggerType)7;
					WriteElement<DropFromTablesOnGameplayEvent>(entityManager, val5, 0, value);
				}
				WriteBuff(world, val6, brewDefinition2.DurationSeconds, brewDefinition2.PersistsThroughDeath, removableByPlayer: true, brewDefinition2.Stats, brewDefinition2.Name, trace);
				PrefabGUID[] array3 = (PrefabGUID[])(object)new PrefabGUID[5]
				{
					SourceItemGuid(prefabLookupMap),
					array2[0],
					array2[1],
					array2[2],
					array2[3]
				};
				PrefabGUID[] array4 = (PrefabGUID[])(object)new PrefabGUID[5] { val7, brewDefinition2.GroupGuid, brewDefinition2.CastGuid, brewDefinition2.ActivateGuid, brewDefinition2.BuffGuid };
				((PrefabLookupMap)(ref prefabLookupMap)).TryGetValueWithoutLogging(array3[0], ref val9);
				Entity[] array5 = (Entity[])(object)new Entity[5]
				{
					val9,
					array[0],
					array[1],
					array[2],
					array[3]
				};
				Entity[] array6 = (Entity[])(object)new Entity[5] { val8, val3, val4, val5, val6 };
				Entity[] array7 = (Entity[])(object)new Entity[4] { val3, val4, val5, val6 };
				foreach (Entity entity in array7)
				{
					for (int l = 0; l < array3.Length; l++)
					{
						foreach (string item in PrefabMemory.Find(entityManager, entity, array3[l], array4[l]))
						{
							Repointed.Add(item);
						}
						if (((Entity)(ref array5[l])).Equals(Entity.Null))
						{
							continue;
						}
						foreach (string item2 in PrefabMemory.FindEntity(entityManager, entity, array5[l], array6[l]))
						{
							Repointed.Add(item2 + " (entity)");
						}
					}
				}
			}
			SealDefinition[] all2 = SealCatalog.All;
			foreach (SealDefinition sealDefinition in all2)
			{
				trace("[" + world.Name + "] building the seal " + sealDefinition.Name);
				Entity buff = CloneOnce(world, existingSystemManaged, array[3], array2[3], sealDefinition.BuffGuid, sealDefinition.BuffPrefabName);
				WriteBuff(world, buff, 0f, persistsThroughDeath: true, removableByPlayer: false, sealDefinition.Stats, sealDefinition.Name, trace);
			}
			CloneOnce(world, existingSystemManaged, array[3], array2[3], SealCatalog.SetBuffGuid, "Buff_DeepRising_Seal_Complete");
			WriteSealSet(world, trace);
			if (Repointed.Count > 0)
			{
				trace("[" + world.Name + "] repointed to the brews' own links: " + string.Join(", ", Repointed));
			}
			if (LeftOut.Count > 0)
			{
				trace("[" + world.Name + "] not on this side's prefabs, left out: " + string.Join(", ", LeftOut));
			}
			return null;
		}

		private static PrefabGUID SourceItemGuid(PrefabLookupMap lookup)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			PrefabGUID result = default(PrefabGUID);
			((PrefabLookupMap)(ref lookup)).TryGetPrefabGuidWithName("Item_Consumable_PhysicalPowerPotion_T01", ref result, false);
			return result;
		}

		private static bool Present<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_0002: 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)
			if (((EntityManager)(ref entityManager)).HasComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0)))
			{
				return true;
			}
			if (!CustomItemRegistry.IsClient)
			{
				throw new InvalidOperationException(typeof(T).Name + " is not on the prefab it is to be changed on");
			}
			LeftOut.Add(typeof(T).Name);
			return false;
		}

		private static bool PresentWithElements<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			if (!Present<T>(entityManager, entity))
			{
				return false;
			}
			if (BufferLength<T>(entityManager, entity) > 0)
			{
				return true;
			}
			if (!CustomItemRegistry.IsClient)
			{
				throw new InvalidOperationException(typeof(T).Name + " is empty on the prefab it is to be changed on");
			}
			LeftOut.Add(typeof(T).Name);
			return false;
		}

		public static void WriteSealSet(World world, Action<string> trace)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			Entity buff = default(Entity);
			if (world.GetExistingSystemManaged<PrefabCollectionSystem>()._PrefabGuidToEntityMap.TryGetValue(SealCatalog.SetBuffGuid, ref buff))
			{
				WriteBuff(world, buff, 0f, persistsThroughDeath: true, removableByPlayer: false, SealCatalog.SetStats(), "Buff_DeepRising_Seal_Complete", trace);
			}
		}

		private static Entity CloneOnce(World world, PrefabCollectionSystem prefabs, Entity source, PrefabGUID sourceGuid, PrefabGUID guid, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			Entity result = default(Entity);
			if (!prefabs._PrefabGuidToEntityMap.TryGetValue(guid, ref result))
			{
				return PrefabCloner.Clone(world, source, sourceGuid, guid, name, ownAsset: true);
			}
			return result;
		}

		private static void WriteBuff(World world, Entity buff, float durationSeconds, bool persistsThroughDeath, bool removableByPlayer, BrewStat[] stats, string name, Action<string> trace)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0060: 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_004d: 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_0031: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0058: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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)
			//IL_00a1: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = world.EntityManager;
			if (Present<LifeTime>(entityManager, buff))
			{
				LifeTime value = Read<LifeTime>(entityManager, buff);
				value.Duration = durationSeconds;
				if (durationSeconds == 0f)
				{
					value.EndAction = (LifeTimeEndAction)0;
				}
				Write<LifeTime>(entityManager, buff, value);
			}
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<UserRemovableBuff>(), (AccessMode)0);
			if (!removableByPlayer && ((EntityManager)(ref entityManager)).HasComponent(buff, val))
			{
				((EntityManager)(ref entityManager)).RemoveComponent(buff, val);
			}
			if (Present<BuffCategory>(entityManager, buff))
			{
				BuffCategory value2 = Read<BuffCategory>(entityManager, buff);
				value2.Groups = (BuffCategoryFlag)0;
				Write<BuffCategory>(entityManager, buff, value2);
			}
			if (PresentWithElements<RemoveBuffOnGameplayEventEntry>(entityManager, buff))
			{
				RemoveBuffOnGameplayEventEntry value3 = ReadElement<RemoveBuffOnGameplayEventEntry>(entityManager, buff, 0);
				value3.BuffCategoryFlag = (BuffCategoryFlag)0;
				WriteElement<RemoveBuffOnGameplayEventEntry>(entityManager, buff, 0, value3);
			}
			ComponentType val2 = default(ComponentType);
			((ComponentType)(ref val2))..ctor(Il2CppType.Of<Buff_Persists_Through_Death>(), (AccessMode)0);
			if (!persistsThroughDeath && ((EntityManager)(ref entityManager)).HasComponent(buff, val2))
			{
				((EntityManager)(ref entityManager)).RemoveComponent(buff, val2);
			}
			if (!PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, buff))
			{
				return;
			}
			int num = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, buff);
			ModifyUnitStatBuff_DOTS val3 = ReadElement<ModifyUnitStatBuff_DOTS>(entityManager, buff, 0);
			for (int i = 0; i < stats.Length; i++)
			{
				ModifyUnitStatBuff_DOTS val4 = val3;
				val4.StatType = stats[i].Stat;
				val4.ModificationType = (ModificationType)3;
				val4.Value = stats[i].Value;
				val4.AttributeCapType = (AttributeCapType)(-1);
				if (i < num)
				{
					WriteElement<ModifyUnitStatBuff_DOTS>(entityManager, buff, i, val4);
					continue;
				}
				trace($"[{world.Name}] {name}: adding stat entry {i}");
				((EntityManager)(ref entityManager)).GetBuffer<ModifyUnitStatBuff_DOTS>(buff, false).Add(val4);
			}
		}

		public static List<string> Verify(World world)
		{
			//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)
			//IL_0015: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0054: 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_005f: 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_0072: 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_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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			EntityManager entityManager = world.EntityManager;
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			PrefabLookupMap prefabLookupMap = existingSystemManaged._PrefabLookupMap;
			int num = 0;
			BrewDefinition[] all = BrewCatalog.All;
			Entity entity = default(Entity);
			Entity entity2 = default(Entity);
			Entity entity3 = default(Entity);
			Entity val = default(Entity);
			PrefabGUID val2 = default(PrefabGUID);
			foreach (BrewDefinition brewDefinition in all)
			{
				List<string> list2 = new List<string>();
				bool num2 = existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.GroupGuid, ref entity) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.CastGuid, ref entity2) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.ActivateGuid, ref entity3) & existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(brewDefinition.BuffGuid, ref val);
				Entity entity4 = Entity.Null;
				if (!(num2 & (((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val2, false) && existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(val2, ref entity4))))
				{
					list2.Add("a prefab of the chain is missing");
				}
				else
				{
					if (Present<CastAbilityOnConsume>(entityManager, entity4))
					{
						CastAbilityOnConsume val3 = Read<CastAbilityOnConsume>(entityManager, entity4);
						if (((PrefabGUID)(ref val3.AbilityGuid)).GuidHash != ((PrefabGUID)(ref brewDefinition.GroupGuid)).GuidHash)
						{
							list2.Add("the item casts another ability");
						}
					}
					if (PresentWithElements<AbilityGroupStartAbilitiesBuffer>(entityManager, entity))
					{
						AbilityGroupStartAbilitiesBuffer val4 = ReadElement<AbilityGroupStartAbilitiesBuffer>(entityManager, entity, 0);
						if (((PrefabGUID)(ref val4.PrefabGUID)).GuidHash != ((PrefabGUID)(ref brewDefinition.CastGuid)).GuidHash)
						{
							list2.Add("the group starts another cast");
						}
					}
					if (Present<AbilityState>(entityManager, entity2))
					{
						AbilityState val5 = Read<AbilityState>(entityManager, entity2);
						if (((PrefabGUID)(ref val5.AbilityId)).GuidHash != ((PrefabGUID)(ref brewDefinition.CastGuid)).GuidHash)
						{
							list2.Add("the cast has another ability id");
						}
					}
					if (PresentWithElements<AbilitySpawnPrefabOnCast>(entityManager, entity2))
					{
						AbilitySpawnPrefabOnCast val6 = ReadElement<AbilitySpawnPrefabOnCast>(entityManager, entity2, 0);
						if (((PrefabGUID)(ref val6.SpawnPrefab)).GuidHash != ((PrefabGUID)(ref brewDefinition.ActivateGuid)).GuidHash)
						{
							list2.Add("the cast spawns another activation");
						}
					}
					if (PresentWithElements<ApplyBuffOnGameplayEvent>(entityManager, entity3))
					{
						ApplyBuffOnGameplayEvent val7 = ReadElement<ApplyBuffOnGameplayEvent>(entityManager, entity3, 0);
						if (((PrefabGUID)(ref val7.Buff0)).GuidHash != ((PrefabGUID)(ref brewDefinition.BuffGuid)).GuidHash)
						{
							list2.Add("the activation applies another buff");
						}
					}
					if (Present<LifeTime>(entityManager, val) && Read<LifeTime>(entityManager, val).Duration != brewDefinition.DurationSeconds)
					{
						list2.Add("the buff has another duration");
					}
					int num3 = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, val);
					if (PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, val))
					{
						if (num3 != brewDefinition.Stats.Length)
						{
							list2.Add($"the buff has {num3} stats, the brew {brewDefinition.Stats.Length}");
						}
						else
						{
							for (int j = 0; j < num3; j++)
							{
								ModifyUnitStatBuff_DOTS val8 = ReadElement<ModifyUnitStatBuff_DOTS>(entityManager, val, j);
								if (val8.StatType != brewDefinition.Stats[j].Stat || val8.Value != brewDefinition.Stats[j].Value)
								{
									list2.Add($"stat {j} is {val8.StatType} {val8.Value}");
								}
							}
						}
					}
					bool flag = ((EntityManager)(ref entityManager)).HasComponent(val, new ComponentType(Il2CppType.Of<Buff_Persists_Through_Death>(), (AccessMode)0));
					if (!CustomItemRegistry.IsClient && flag != brewDefinition.PersistsThroughDeath)
					{
						list2.Add($"persists through death: {flag}");
					}
				}
				if (list2.Count == 0)
				{
					num++;
				}
				else
				{
					list.Add("verify FAIL brew " + brewDefinition.Name + ": " + string.Join("; ", list2));
				}
			}
			int num4 = 0;
			SealDefinition[] all2 = SealCatalog.All;
			Entity val9 = default(Entity);
			foreach (SealDefinition sealDefinition in all2)
			{
				List<string> list3 = new List<string>();
				if (!existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(sealDefinition.BuffGuid, ref val9))
				{
					list3.Add("no prefab");
				}
				else
				{
					if (Present<LifeTime>(entityManager, val9) && (int)Read<LifeTime>(entityManager, val9).EndAction != 0)
					{
						list3.Add("the buff runs out");
					}
					if (((EntityManager)(ref entityManager)).HasComponent(val9, new ComponentType(Il2CppType.Of<UserRemovableBuff>(), (AccessMode)0)))
					{
						list3.Add("the player can take it off");
					}
					int num5 = BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, val9);
					if (PresentWithElements<ModifyUnitStatBuff_DOTS>(entityManager, val9) && num5 != sealDefinition.Stats.Length)
					{
						list3.Add($"the buff has {num5} stats, the seal {sealDefinition.Stats.Length}");
					}
				}
				if (list3.Count == 0)
				{
					num4++;
				}
				else
				{
					list.Add("verify FAIL seal " + sealDefinition.Name + ": " + string.Join("; ", list3));
				}
			}
			Entity entity5 = default(Entity);
			bool flag2 = existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(SealCatalog.SetBuffGuid, ref entity5);
			int value = (flag2 ? BufferLength<ModifyUnitStatBuff_DOTS>(entityManager, entity5) : 0);
			list.Add($"verify summary: {num4}/{SealCatalog.All.Length} seals OK; set of all: " + (flag2 ? $"{value} stats, {SealCatalog.SetMultiplierText(polish: false)}" : "no prefab"));
			list.Add($"verify summary: {num}/{BrewCatalog.All.Length} brews OK" + ((LeftOut.Count > 0) ? ("; not on this side's prefabs: " + string.Join(", ", LeftOut)) : "") + ((Repointed.Count > 0) ? ("; repointed: " + string.Join(", ", Repointed)) : ""));
			return list;
		}

		public static List<string> RegisterClientData(World world, Action<string> trace)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Expected O, but got Unknown
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Expected O, but got Unknown
			List<string> list = new List<string>();
			PrefabLookupMap prefabLookupMap = world.GetExistingSystemManaged<PrefabCollectionSystem>()._PrefabLookupMap;
			ManagedDataRegistry managedDataRegistry = world.GetExistingSystemManaged<GameDataSystem>().ManagedDataRegistry;
			Dictionary<PrefabLookupKey, Object> dataLookupMap = managedDataRegistry._DataLookupMap;
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			PrefabGUID val = default(PrefabGUID);
			for (int i = 0; i < SourceNames.Length; i++)
			{
				if (((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(SourceNames[i], ref val, false))
				{
					dictionary[((PrefabGUID)(ref val)).GuidHash] = i;
				}
			}
			List<(int, Type, Object)> list2 = new List<(int, Type, Object)>();
			HashSet<(int, string)> hashSet = new HashSet<(int, string)>();
			Enumerator<PrefabLookupKey, Object> enumerator = dataLookupMap.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<PrefabLookupKey, Object> current = enumerator.Current;
				if (current.Value != null)
				{
					PrefabGUID prefabGUID = current.Key.PrefabGUID;
					int guidHash = ((PrefabGUID)(ref prefabGUID)).GuidHash;
					if (dictionary.TryGetValue(guidHash, out var value))
					{
						list2.Add((value, current.Key.ComponentType, current.Value));
					}
					else
					{
						hashSet.Add((guidHash, current.Key.ComponentType.FullName));
					}
				}
			}
			foreach (var item in list2)
			{
				list.Add($"brew interface data: {SourceNames[item.Item1]} has {((MemberInfo)item.Item3.GetIl2CppType()).Name} (as {((MemberInfo)item.Item2).Name})");
			}
			if (list2.Count == 0)
			{
				list.Add("brew interface data: the game keeps none for the source potion's ability and buff");
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			BrewDefinition[] all = BrewCatalog.All;
			PrefabGUID val2 = default(PrefabGUID);
			foreach (BrewDefinition brewDefinition in all)
			{
				if (!((PrefabLookupMap)(ref prefabLookupMap)).TryGetPrefabGuidWithName(brewDefinition.ItemPrefabName, ref val2, false))
				{
					continue;
				}
				ManagedItemData orDefaultWithoutLogging = managedDataRegistry.GetOrDefaultWithoutLogging<ManagedItemData>(val2, (ManagedItemData)null);
				PrefabGUID[] array = (PrefabGUID[])(object)new PrefabGUID[4] { brewDefinition.GroupGuid, brewDefinition.CastGuid, brewDefinition.ActivateGuid, brewDefinition.BuffGuid };
				foreach (var item2 in list2)
				{
					PrefabGUID prefabGUID2 = array[item2.Item1];
					if (hashSet.Contains((((PrefabGUID)(ref prefabGUID2)).GuidHash, item2.Item2.FullName)))
					{
						continue;
					}
					try
					{
						Object value2 = item2.Item3;
						if (orDefaultWithoutLogging != null && ((Il2CppObjectBase)item2.Item3).TryCast<ManagedItemData>() != null)
						{
							value2 = (Object)(object)orDefaultWithoutLogging;
							num++;
						}
						else if (orDefaultWithoutLogging != null && ((Il2CppObjectBase)item2.Item3).TryCast<ManagedAbilityGroupData>() != null)
						{
							value2 = (Object)new ManagedAbilityGroupData
							{
								Name = orDefaultWithoutLogging.Name,
								Description = orDefaultWithoutLogging.Description,
								Icon = orDefaultWithoutLogging.Icon
							};
							num++;
						}
						else
						{
							num2++;
						}
						trace($"[{world.Name}] {((MemberInfo)item2.Item3.GetIl2CppType()).Name} of {SourceNames[item2.Item1]} for {((PrefabGUID)(ref prefabGUID2)).GuidHash}");
						PrefabLookupKey boxedKey = new PrefabLookupKey
						{
							PrefabGUID = prefabGUID2,
							ComponentType = item2.Item2
						};
						Il2CppDictionary.AddWithUnboxedKey((Il2CppObjectBase)(object)dataLookupMap, (Il2CppObjectBase)(object)boxedKey, (Il2CppObjectBase)(object)value2);
					}
					catch (Exception ex)
					{
						num3++;
						list.Add($"brew interface data: entry for {((PrefabGUID)(ref prefabGUID2)).GuidHash} failed: {ex.Message}");
					}
				}
			}
			list.Add($"brew interface data: {num} entries with the brew's own name and icon, {num2} shared with the source, {num3} failed");
			if (BuffBarWriter != null)
			{
				list.Add(BuffBarWriter(world));
			}
			return list;
		}

		private unsafe static void SetGuid<T>(EntityManager entityManager, Entity entity, string field, PrefabGUID guid) where T : struct
		{
			//IL_000f: 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_0011: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* componentDataRawRW = (byte*)((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, val.TypeIndex);
			Unsafe.Write(componentDataRawRW + (int)Marshal.OffsetOf<T>(field), guid);
		}

		private unsafe static void SetGuidInBuffer<T>(EntityManager entityManager, Entity entity, string field, PrefabGUID guid) where T : struct
		{
			//IL_000f: 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_0011: 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_003f: 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_0058: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			if (((EntityManager)(ref entityManager)).GetBufferLength(entity, val.TypeIndex) == 0)
			{
				throw new InvalidOperationException(typeof(T).Name + " is empty on the prefab it is to be changed on");
			}
			byte* bufferRawRW = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRW(entity, val.TypeIndex);
			Unsafe.Write(bufferRawRW + (int)Marshal.OffsetOf<T>(field), guid);
		}

		private unsafe static T Read<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			return Marshal.PtrToStructure<T>(new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, val.TypeIndex)));
		}

		private unsafe static void Write<T>(EntityManager entityManager, Entity entity, T value) where T : struct
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			Marshal.StructureToPtr(value, new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, val.TypeIndex)), fDeleteOld: false);
		}

		private static int BufferLength<T>(EntityManager entityManager, Entity entity) where T : struct
		{
			//IL_000f: 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_001c: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			if (!((EntityManager)(ref entityManager)).HasComponent(entity, val))
			{
				return 0;
			}
			return ((EntityManager)(ref entityManager)).GetBufferLength(entity, val.TypeIndex);
		}

		private unsafe static T ReadElement<T>(EntityManager entityManager, Entity entity, int index) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* bufferRawRO = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRO(entity, val.TypeIndex);
			return Marshal.PtrToStructure<T>(new IntPtr(bufferRawRO + index * Marshal.SizeOf<T>()));
		}

		private unsafe static void WriteElement<T>(EntityManager entityManager, Entity entity, int index, T value) where T : struct
		{
			//IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte* bufferRawRW = (byte*)((EntityManager)(ref entityManager)).GetBufferRawRW(entity, val.TypeIndex);
			Marshal.StructureToPtr(value, new IntPtr(bufferRawRW + index * Marshal.SizeOf<T>()), fDeleteOld: false);
		}
	}
	internal sealed class PrisonerFeedEffect
	{
		public float HealthMin;

		public float HealthMax;

		public float MiseryReliefMin;

		public float MiseryReliefMax;

		public float BloodQualityBonus;

		public bool BloodQualityStaysInTier;

		public float DrainHealthFactor = 1f;

		public bool FreezesMisery;

		public bool Lasts
		{
			get
			{
				if (!(DrainHealthFactor < 1f))
				{
					return FreezesMisery;
				}
				return true;
			}
		}
	}
	internal struct IconTint
	{
		public float Hue;

		public float Saturation;

		public IconTint(float hue, float saturation)
		{
			Hue = hue;
			Saturation = saturation;
		}
	}
	internal sealed class FishDescription
	{
		public readonly string SourceItem;

		public readonly string RarityWord;

		public readonly string RarityWordPl;

		public FishDescription(string sourceItem, string rarityWord, string rarityWordPl)
		{
			SourceItem = sourceItem;
			RarityWord = rarityWord;
			RarityWordPl = rarityWordPl;
		}
	}
	internal sealed class CustomItemDefinition
	{
		private const int NameKeyA = 1146179585;

		private const int NameKeyB = 1380207439;

		private const int NameKeyC = 1112493125;

		private const int DescriptionKeyC = 1112493126;

		public PrefabGUID Guid;

		public string PrefabName;

		public string DisplayName;

		public string DisplayNamePl;

		public string SourceItemName;

		public PrisonerFeedEffect Feed;

		public string IconName;

		public IconTint IconTint;

		public int IconMarks;

		public FishDescription Description;

		public BrewDefinition Brew;

		public Func<bool, string> OwnDescription;

		public float WeaponLevel;

		public AssetGuid NameKey => NameKeyOf(Guid);

		public AssetGuid DescriptionKey => DescriptionKeyOf(Guid);

		public static AssetGuid NameKeyOf(PrefabGUID guid)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new AssetGuid(1146179585, 1380207439, 1112493125, ((PrefabGUID)(ref guid)).GuidHash);
		}

		public static AssetGuid DescriptionKeyOf(PrefabGUID guid)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new AssetGuid(1146179585, 1380207439, 1112493126, ((PrefabGUID)(ref guid)).GuidHash);
		}
	}
	internal static class CustomItemCatalog
	{
		private const int FirstGuid = 1146179585;

		public const string FishPrefabPrefix = "Item_Ingredient_Fish_DeepRising_";

		public const string FeedPrefabPrefix = "FakeItem_FeedPrisoner_DeepRising_";

		private const string FishSource = "Item_Ingredient_Fish_FatGoby_T01";

		private const string FeedSource = "FakeItem_FeedPrisoner_FatGoby";

		private const string BrewIconPrefix = "Brew";

		private const string AccessorySource = "Item_Ingredient_FishBone";

		private const string AccessoryIconPrefix = "Accessory_";

		private const string RodIconPrefix = "Rod";

		private const int FirstRodTier = 2;

		private static readonly IconTint[] AccessoryTints = new IconTint[4]
		{
			new IconTint(0.12f, 0.35f),
			new IconTint(0.6f, 0.9f),
			new IconTint(0.07f, 1.1f),
			new IconTint(0.58f, 0.1f)
		};

		private static readonly IconTint[] RodTints = new IconTint[3]
		{
			new IconTint(0.58f, 0.45f),
			new IconTint(0.55f, 0.05f),
			new IconTint(0.98f, 1.2f)
		};

		private const int FishPerRarity = 4;

		private static readonly FishDescription[] DescriptionsByRarity = new FishDescription[3]
		{
			new FishDescription("Item_Ingredient_Fish_SageFish_T02", null, null),
			new FishDescription("Item_Ingredient_Fish_GoldenRiverBass_T03", null, null),
			new FishDescription("Item_Ingredient_Fish_GoldenRiverBass_T03", "legendary", "Legendarna")
		};

		private const float Full = 1f;

		private static readonly PrisonerFeedEffect UncommonFeed = Feed(0.4f, 0.6f, 0.1f, 0.2f);

		private static readonly PrisonerFeedEffect RareFeed = Feed(0.7f, 1f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect LegendaryFeed = Feed(1f, 1f, 1f, 1f);

		private static readonly PrisonerFeedEffect UncommonShadowFeed = Feed(0.4f, 0.6f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect RareShadowFeed = Feed(0.7f, 1f, 0.5f, 0.6f);

		private static readonly PrisonerFeedEffect UncommonSlaughterFeed = Feed(0.8f, 1f, 0.1f, 0.2f);

		private static readonly PrisonerFeedEffect RareSlaughterFeed = Feed(1f, 1f, 0.25f, 0.35f);

		private static readonly PrisonerFeedEffect SturgeonFeed = Lasting(RareSlaughterFeed, 0.5f, freezesMisery: false);

		private static readonly PrisonerFeedEffect VoltfangFeed = Lasting(LegendaryFeed, 0f, freezesMisery: false);

		private static readonly PrisonerFeedEffect LeviathanFeed = Lasting(LegendaryFeed, 1f, freezesMisery: true);

		private static readonly PrisonerFeedEffect RareBloodFeed = Feed(0.7f, 1f, 0.25f, 0.35f, 1f, bloodQualityStaysInTier: true);

		private static readonly PrisonerFeedEffect LegendaryBloodFeed = Feed(1f, 1f, 1f, 1f, 5f);

		public static readonly CustomItemDefinition[] All = Build();

		public static CustomItemDefinition Find(PrefabGUID guid)
		{
			CustomItemDefinition[] all = All;
			foreach (CustomItemDefinition customItemDefinition in all)
			{
				if (((PrefabGUID)(ref customItemDefinition.Guid)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash)
				{
					return customItemDefinition;
				}
			}
			return null;
		}

		private static CustomItemDefinition[] Build()
		{
			(string, string, string, PrisonerFeedEffect, IconTint)[] array = new(string, string, string, PrisonerFeedEffect, IconTint)[12]
			{
				("AshgillPerch", "Ashgill Perch", "Okoń popielnoskrzeli", UncommonFeed, new IconTint(0.08f, 0.25f)),
				("VeinfinMinnow", "Veinfin Minnow", "Strzebla żyłopłetwa", UncommonFeed, new IconTint(0.95f, 0.7f)),
				("DuskscaleCarp", "Duskscale Carp", "Karp zmierzchołuski", UncommonShadowFeed, new IconTint(0.74f, 0.7f)),
				("IronjawChub", "Ironjaw Chub", "Kleń żelaznoszczęki", UncommonSlaughterFeed, new IconTint(0.6f, 0.2f)),
				("GravetoothPike", "Gravetooth Pike", "Szczupak grobozęby", RareFeed, new IconTint(0.38f, 0.55f)),
				("CrimsonEel", "Crimson Eel", "Karmazynowy węgorz", RareBloodFeed, new IconTint(0f, 1f)),
				("EclipseKoi", "Eclipse Koi", "Koi zaćmienia", RareShadowFeed, new IconTint(0.08f, 1.1f)),
				("StormgillSturgeon", "Stormgill Sturgeon", "Jesiotr burzoskrzeli", SturgeonFeed, new IconTint(0.64f, 1f)),
				("OldMossback", "Old Mossback", "Stary Mchogrzbiet", LegendaryFeed, new IconTint(0.27f, 1f)),
				("CrimsonMatriarch", "Crimson Matriarch", "Karmazynowa Matrona", LegendaryBloodFeed, new IconTint(0.93f, 1.3f)),
				("ArgentLeviathan", "Argent Leviathan", "Srebrny Lewiatan", LeviathanFeed, new IconTint(0.55f, 0.05f)),
				("Voltfang", "Voltfang", "Piorunokieł", VoltfangFeed, new IconTint(0.15f, 1.3f))
			};
			List<CustomItemDefinition> items = new List<CustomItemDefinition>();
			for (int i = 0; i < array.Length; i++)
			{
				(string, string, string, PrisonerFeedEffect, IconTint) tuple = array[i];
				Add("Item_Ingredient_Fish_DeepRising_", "Item_Ingredient_Fish_FatGoby_T01", tuple.Item1, tuple.Item2, tuple.Item3, null, tuple.Item5);
				items[items.Count - 1].Description = DescriptionsByRarity[i / 4];
			}
			(string, string, string, PrisonerFeedEffect, IconTint)[] array2 = array;
			for (int j = 0; j < array2.Length; j++)
			{
				(string, string, string, PrisonerFeedEffect, IconTint) tuple2 = array2[j];
				Add("FakeItem_FeedPrisoner_DeepRising_", "FakeItem_FeedPrisoner_FatGoby", tuple2.Item1, tuple2.Item2, tuple2.Item3, tuple2.Item4, tuple2.Item5);
			}
			BrewDefinition[] all = BrewCatalog.All;
			foreach (BrewDefinition brewDefinition in all)
			{
				Add("Item_Consumable_DeepRising_Brew_", "Item_Consumable_PhysicalPowerPotion_T01", brewDefinition.Name, brewDefinition.DisplayName, brewDefinition.DisplayNamePl, null, brewDefinition.IconTint);
				items[items.Count - 1].IconName = "Brew" + brewDefinition.Name;
				items[items.Count - 1].IconMarks = brewDefinition.Tier;
				items[items.Count - 1].Brew = brewDefinition;
			}
			for (int k = 0; k < AccessoryCatalog.All.Length; k++)
			{
				Accessory accessory = AccessoryCatalog.All[k];
				Add(string.Empty, "Item_Ingredient_FishBone", accessory.Item, accessory.Name, accessory.NamePl, null, AccessoryTints[k % AccessoryTints.Length]);
				CustomItemDefinition customItemDefinition = items[items.Count - 1];
				customItemDefinition.IconName = "Accessory_" + accessory.Id;
				customItemDefinition.OwnDescription = (bool polish) => (!polish) ? ("A rod accessory: " + accessory.Description + ". It works while you carry it and have chosen it in the bait window; one accessory at a time.") : ("Akcesorium do wędki: " + accessory.DescriptionPl + ". Działa, gdy masz je przy sobie i wybierzesz w oknie przynęt; naraz jedno akcesorium.");
			}
			RodItem[] all2 = RodCatalog.All;
			foreach (RodItem rod in all2)
			{
				Add(string.Empty, "Item_Weapon_FishingPole_T01", rod.Item, rod.Name, rod.NamePl, null, RodTints[(rod.Tier - 2) % RodTints.Length]);
				CustomItemDefinition customItemDefinition2 = items[items.Count - 1];
				customItemDefinition2.IconName = "Rod" + rod.Tier;
				customItemDefinition2.WeaponLevel = rod.WeaponLevel;
				customItemDefinition2.OwnDescription = (bool polish) => polish ? $"Wędka poziomu {rod.Tier}: +{rod.QualityPoints} do jakości połowu. Liczy się najlepsza wędka, jaką masz przy sobie." : $"A fishing pole of tier {rod.Tier}: +{rod.QualityPoints} catch quality. The best pole you have with you is the one that counts.";
			}
			return items.ToArray();
			void Add(string prefix, string source, string name, string displayName, string displayNamePl, PrisonerFeedEffect feed, IconTint tint)
			{
				//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)
				items.Add(new CustomItemDefinition
				{
					Guid = new PrefabGUID(1146179585 + items.Count),
					PrefabName = prefix + name,
					DisplayName = displayName,
					DisplayNamePl = displayNamePl,
					SourceItemName = source,
					Feed = feed,
					IconName = name,
					IconTint = tint
				});
			}
		}

		private static PrisonerFeedEffect Lasting(PrisonerFeedEffect feed, float drainHealthFactor, bool freezesMisery)
		{
			return new PrisonerFeedEffect
			{
				HealthMin = feed.HealthMin,
				HealthMax = feed.HealthMax,
				MiseryReliefMin = feed.MiseryReliefMin,
				MiseryReliefMax = feed.MiseryReliefMax,
				BloodQualityBonus = feed.BloodQualityBonus,
				BloodQualityStaysInTier = feed.BloodQualityStaysInTier,
				DrainHealthFactor = drainHealthFactor,
				FreezesMisery = freezesMisery
			};
		}

		private static PrisonerFeedEffect Feed(float healthMin, float healthMax, float miseryReliefMin, float miseryReliefMax, float bloodQualityBonus = 0f, bool bloodQualityStaysInTier = false)
		{
			return new PrisonerFeedEffect
			{
				HealthMin = healthMin,
				HealthMax = healthMax,
				MiseryReliefMin = miseryReliefMin,
				MiseryReliefMax = miseryReliefMax,
				BloodQualityBonus = bloodQualityBonus,
				BloodQualityStaysInTier = bloodQualityStaysInTier
			};
		}
	}
	internal static class CustomItemRegistry
	{
		private sealed class WorldProgress
		{
			public bool PrefabsRegistered;

			public bool RecipesRegistered;

			public bool BrewsRegistered;

			public bool BrewDataRegistered;

			public bool BrewsFailed;

			public string LastBrewWaitReason;

			public bool TableExtended;

			public bool NamesRegistered;

			public bool Failed;

			public string LastWaitReason;

			public bool Complete
			{
				get
				{
					if (PrefabsRegistered && RecipesRegistered && TableExtended)
					{
						return NamesRegistered;
					}
					return false;
				}
			}
		}

		[HarmonyPatch(typeof(PrefabCollectionSystem), "OnUpdate")]
		private static class PrefabSystemPatch
		{
			private static void Prefix(PrefabCollectionSystem __instance)
			{
				Pump(((ComponentSystemBase)__instance).World);
			}
		}

		public const int KnownVanillaItemCount = 1083;

		private const string PolishLanguage = "polish";

		private const string EnglishLanguage = "english";

		private const string FeedDescriptionSourceItem = "FakeItem_FeedPrisoner_GoldenRiverBass";

		private const float PercentPerUnit = 100f;

		private const string BloodChangeBuffSourceItem = "FakeItem_FeedPrisoner_Corrupted";

		private const string HighlightOpen = "<color=#82C9D9>";

		private const string HighlightClose = "</color>";

		public static bool IsClient;

		public static Action<string> Log = delegate
		{
		};

		public static Func<CustomItemDefinition, Sprite, Sprite> IconProvider;

		public static Action<string> TraceSink;

		private static readonly Dictionary<ulong, WorldProgress> Worlds = new Dictionary<ulong, WorldProgress>();

		private static readonly HashSet<ulong> ServerHasMod = new HashSet<ulong>();

		private static readonly HashSet<int> InTable = new HashSet<int>();

		public static void ServerAnnouncedMod(World world)
		{
			ServerHasMod.Add(world.SequenceNumber);
		}

		public static bool ArePrefabsRegistered(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value) && value.PrefabsRegistered && value.RecipesRegistered)
			{
				if (!value.BrewsRegistered)
				{
					return value.BrewsFailed;
				}
				return true;
			}
			return false;
		}

		public static bool IsReadyForBuffs(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value) && value.Complete)
			{
				if (!value.BrewsRegistered)
				{
					return value.BrewsFailed;
				}
				return true;
			}
			return false;
		}

		public static bool IsComplete(World world)
		{
			if (Worlds.TryGetValue(world.SequenceNumber, out var value))
			{
				return value.Complete;
			}
			return false;
		}

		public static void Pump(World world)
		{
			if (!HasPrefabSystems(world))
			{
				return;
			}
			if (!Worlds.TryGetValue(world.SequenceNumber, out var value))
			{
				value = (Worlds[world.SequenceNumber] = new WorldProgress());
			}
			if (value.Failed)
			{
				return;
			}
			bool flag = !IsClient || ServerHasMod.Contains(world.SequenceNumber);
			try
			{
				long started = FrameTimings.Start();
				foreach (string item in PrefabCloner.Audit(world))
				{
					Report(world, "prefab audit: " + item);
				}
				FrameTimings.Stop("items: audit", started);
				if (value.Complete)
				{
					started = FrameTimings.Start();
					PumpBrews(world, value);
					FrameTimings.Stop("items: brews", started);
					started = FrameTimings.Start();
					MaintainItemTable(world, value);
					FrameTimings.Stop("items: table", started);
					return;
				}
				if (!value.PrefabsRegistered)
				{
					if (!TryRegisterPrefabs(world))
					{
						return;
					}
					value.PrefabsRegistered = true;
					Report(world, $"{CustomItemCatalog.All.Length} custom item prefabs registered");
				}
				PumpBrews(world, value);
				if (!flag)
				{
					return;
				}
				if (!value.RecipesRegistered)
				{
					if (!CustomRecipeRegistry.TryRegisterPrefabs(world, Trace))
					{
						return;
					}
					value.RecipesRegistered = true;
					Report(world, $"{CustomRecipeCatalog.All.Length} custom recipe prefabs registered");
				}
				if (!value.TableExtended)
				{
					string text = TryExtendItemTable(world);
					if (text != null)
					{
						if (text != value.LastWaitReason)
						{
							Report(world, "item table not extended yet: " + text);
						}
						value.LastWaitReason = text;
						return;
					}
					value.TableExtended = true;
				}
				if (!value.NamesRegistered)
				{
					if (IsClient && !TryRegisterNames(world))
					{
						return;
					}
					value.NamesRegistered = true;
				}
				PumpBrews(world, value);
				if (IsClient)
				{
					RegisterTechNames(world);
				}
				AddRecipesToStations(world);
				foreach (string item2 in Verify(world))
				{
					Report(world, item2);
				}
				foreach (string item3 in CustomRecipeRegistry.Verify(world))
				{
					Report(world, item3);
				}
			}
			catch (Exception value2)
			{
				value.Failed = true;
				Report(world, $"FAILED, giving up in this world: {value2}");
			}
		}

		private static bool HasPrefabSystems(World world)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			if (world == null || !world.IsCreated)
			{
				return false;
			}
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			if (existingSystemManaged != null && world.GetExistingSystemManaged<GameDataSystem>() != null && existingSystemManaged._PrefabGuidToEntityMap.IsCreated)
			{
				return existingSystemManaged._PrefabDataLookup.IsCreated;
			}
			return false;
		}

		public static void SetGearBalance(GearBalance balance, World world)
		{
			GearBalance.Current = balance;
			BrewCatalog.Refresh();
			SealCatalog.Refresh();
			CustomRecipeCatalog.Refresh();
			if (world != null && Worlds.TryGetValue(world.SequenceNumber, out var value) && value.BrewsRegistered)
			{
				value.BrewsRegistered = false;
				Report(world, "the server's values differ from those the brews were built with; building them again");
			}
		}

		private static void PumpBrews(World world, WorldProgress progress)
		{
			if (progress.BrewsFailed)
			{
				return;
			}
			try
			{
				PumpBrewStages(world, progress);
			}
			catch (Exception value)
			{
				progress.BrewsFailed = true;
				Report(world, $"brews FAILED, giving up on them in this world: {value}");
			}
		}

		private static void RegisterTechNames(World world)
		{
			try
			{
				foreach (string item in CustomRecipeRegistry.RegisterTechNames(world, IsPolish()))
				{
					Report(world, item);
				}
			}
			catch (Exception value)
			{
				Report(world, $"tech names FAILED: {value}");
			}
		}

		private static void PumpBrewStages(World world, WorldProgress progress)
		{
			if (!progress.BrewsRegistered)
			{
				string text = CustomBrewRegistry.TryRegisterPrefabs(world, Trace);
				if (text != null)
				{
					if (text != progress.LastBrewWaitReason)
					{
						Report(world, "brews not registered yet: " + text);
					}
					progress.LastBrewWaitReason = text;

plugins/DeepRising/DeepRising.Shared.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DeepRising.Shared")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+60570d036cb645189aa435c34b42d7162430cee3")]
[assembly: AssemblyProduct("DeepRising.Shared")]
[assembly: AssemblyTitle("DeepRising.Shared")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DeepRising.Shared
{
	public sealed class VBloodTeacher
	{
		public string Unit;

		public string Tech;

		public string Name;

		public string NamePl;

		public string NameIn(string language)
		{
			if (!(language == "pl"))
			{
				return Name;
			}
			return NamePl;
		}
	}
	public static class VBloodTeachers
	{
		public static readonly VBloodTeacher Finn = new VBloodTeacher
		{
			Unit = "CHAR_Bandit_Fisherman_VBlood",
			Tech = "Tech_Collection_VBlood_T03_Fisherman",
			Name = "Finn the Fisherman",
			NamePl = "Rybak Finn"
		};

		public static readonly VBloodTeacher Quincey = new VBloodTeacher
		{
			Unit = "CHAR_Bandit_Tourok_VBlood",
			Tech = "Tech_Collection_VBlood_T04_Quincey",
			Name = "Quincey the Bandit King",
			NamePl = "Quincey Król Bandytów"
		};

		public static readonly VBloodTeacher Raziel = new VBloodTeacher
		{
			Unit = "CHAR_Militia_BishopOfDunley_VBlood",
			Tech = "Tech_Collection_VBlood_T06_Raziel",
			Name = "Raziel the Shepherd",
			NamePl = "Raziel Pasterz"
		};

		public static readonly VBloodTeacher Ungora = new VBloodTeacher
		{
			Unit = "CHAR_Spider_Queen_VBlood",
			Tech = "Tech_Collection_VBlood_T06_SpiderQueen",
			Name = "Ungora the Spider Queen",
			NamePl = "Ungora Królowa Pająków"
		};

		public static readonly VBloodTeacher Baron = new VBloodTeacher
		{
			Unit = "CHAR_ChurchOfLight_Sommelier_VBlood",
			Tech = "Tech_Collection_VBlood_T07_Sommelier",
			Name = "Baron du Bouchon the Sommelier",
			NamePl = "Baron du Bouchon, Sommelier"
		};

		public static readonly VBloodTeacher Henry = new VBloodTeacher
		{
			Unit = "CHAR_Gloomrot_TheProfessor_VBlood",
			Tech = "Tech_Collection_VBlood_T07_Professor",
			Name = "Henry Blackbrew the Doctor",
			NamePl = "Doktor Henry Blackbrew"
		};
	}
	public enum AccessoryEffect
	{
		LongerReaction,
		FasterBites,
		LessJunk,
		MoreJunk
	}
	public sealed class Accessory
	{
		public string Id;

		public string Item;

		public string Name;

		public string NamePl;

		public List<ItemCost> Cost;

		public AccessoryEffect Effect;

		public string Description => AccessoryRules.Describe(Effect, polish: false);

		public string DescriptionPl => AccessoryRules.Describe(Effect, polish: true);

		public string NameIn(string language)
		{
			if (!(language == "pl"))
			{
				return Name;
			}
			return NamePl;
		}

		public string DescriptionIn(string language)
		{
			if (!(language == "pl"))
			{
				return Description;
			}
			return DescriptionPl;
		}
	}
	public static class AccessoryRules
	{
		private const float PercentPerUnit = 100f;

		private const float Certain = 1f;

		public static float ReelBiteDelayFactor => GearBalance.Current.ReelBiteDelayFactor;

		public static float ReelHaulFactor => GearBalance.Current.ReelHaulFactor;

		public static int ReelHaulShorterByPercent => (int)Math.Round((1f - ReelHaulFactor) * 100f);

		public static float FloatReactionFactor => GearBalance.Current.FloatReactionFactor;

		public static float MagnetJunkFactor => GearBalance.Current.MagnetJunkFactor;

		public static int ReelShorterByPercent => (int)Math.Round((1f - ReelBiteDelayFactor) * 100f);

		public static int FloatLongerByPercent => (int)Math.Round((FloatReactionFactor - 1f) * 100f);

		public static string Describe(AccessoryEffect effect, bool polish)
		{
			switch (effect)
			{
			case AccessoryEffect.LongerReaction:
				if (polish)
				{
					return $"{FloatLongerByPercent}% więcej czasu na zacięcie";
				}
				return $"{FloatLongerByPercent}% more time to hook a bite";
			case AccessoryEffect.FasterBites:
				if (polish)
				{
					return $"czekanie na branie krótsze o {ReelShorterByPercent}%, hol krótszy o {ReelHaulShorterByPercent}%";
				}
				return $"the wait for a bite is {ReelShorterByPercent}% shorter, a haul {ReelHaulShorterByPercent}% shorter";
			case AccessoryEffect.LessJunk:
				if (!polish)
				{
					return "less junk: a late hook no longer makes junk more likely";
				}
				return "mniej śmieci: spóźnione zacięcie nie zwiększa już szansy na śmieć";
			default:
			{
				string text = MagnetJunkFactor.ToString("0.##", CultureInfo.InvariantCulture);
				if (!polish)
				{
					return "more junk: junk comes up " + text + " times as often, fish less often";
				}
				return "więcej śmieci: śmieć trafia się " + text.Replace('.', ',') + " razy częściej, ryba rzadziej";
			}
			}
		}

		public static FishingBalance Apply(FishingBalance balance, Accessory accessory)
		{
			if (accessory == null)
			{
				return balance;
			}
			FishingBalance fishingBalance = balance.Clone();
			switch (accessory.Effect)
			{
			case AccessoryEffect.FasterBites:
				fishingBalance.MinBiteDelaySeconds *= ReelBiteDelayFactor;
				fishingBalance.MaxBiteDelaySeconds *= ReelBiteDelayFactor;
				break;
			case AccessoryEffect.LongerReaction:
				fishingBalance.MaxReactionSeconds *= FloatReactionFactor;
				break;
			case AccessoryEffect.LessJunk:
				fishingBalance.WeakCatchJunkChance = 0f;
				break;
			case AccessoryEffect.MoreJunk:
				fishingBalance.BaseFishChance = 1f - Math.Min(1f, (1f - fishingBalance.BaseFishChance) * MagnetJunkFactor);
				break;
			}
			return fishingBalance;
		}

		public static Accessory ActiveOf(string activeId, ICollection<string> ownedIds)
		{
			Accessory accessory = AccessoryCatalog.Find(activeId);
			if (accessory == null || !Owns(ownedIds, accessory))
			{
				return null;
			}
			return accessory;
		}

		public static bool Owns(ICollection<string> ownedIds, Accessory accessory)
		{
			if (ownedIds == null)
			{
				return false;
			}
			foreach (string ownedId in ownedIds)
			{
				if (string.Equals(ownedId, accessory.Id, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class AccessoryCatalog
	{
		public const string ItemPrefix = "Item_DeepRising_Accessory_";

		public static readonly VBloodTeacher Teacher = VBloodTeachers.Finn;

		private const string FishBones = "Item_Ingredient_FishBone";

		private const string CopperIngot = "Item_Ingredient_Mineral_CopperIngot";

		private const string IronIngot = "Item_Ingredient_Mineral_IronBar";

		public static readonly Accessory[] All = new Accessory[4]
		{
			new Accessory
			{
				Id = "float",
				Item = "Item_DeepRising_Accessory_Float",
				Name = "Bone Float",
				NamePl = "Spławik z kości",
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Ingredient_FishBone",
						DisplayName = "Fish Bones",
						DisplayNamePl = "Ość",
						Amount = 30
					}
				},
				Effect = AccessoryEffect.LongerReaction
			},
			new Accessory
			{
				Id = "reel",
				Item = "Item_DeepRising_Accessory_Reel",
				Name = "Reel",
				NamePl = "Kołowrotek",
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Ingredient_Mineral_CopperIngot",
						DisplayName = "Copper Ingot",
						DisplayNamePl = "Sztabka miedzi",
						Amount = 10
					}
				},
				Effect = AccessoryEffect.FasterBites
			},
			new Accessory
			{
				Id = "sinker",
				Item = "Item_DeepRising_Accessory_Sinker",
				Name = "Sinker",
				NamePl = "Ciężarek",
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Ingredient_Mineral_IronBar",
						DisplayName = "Iron Ingot",
						DisplayNamePl = "Sztabka żelaza",
						Amount = 15
					}
				},
				Effect = AccessoryEffect.LessJunk
			},
			new Accessory
			{
				Id = "magnet",
				Item = "Item_DeepRising_Accessory_Magnet",
				Name = "Magnet",
				NamePl = "Magnes",
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Ingredient_Mineral_IronBar",
						DisplayName = "Iron Ingot",
						DisplayNamePl = "Sztabka żelaza",
						Amount = 10
					}
				},
				Effect = AccessoryEffect.MoreJunk
			}
		};

		public static Accessory Find(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				return null;
			}
			Accessory[] all = All;
			foreach (Accessory accessory in all)
			{
				if (string.Equals(accessory.Id, id, StringComparison.OrdinalIgnoreCase))
				{
					return accessory;
				}
			}
			return null;
		}
	}
	public sealed class RodItem
	{
		public int Tier;

		public string Item;

		public string Name;

		public string NamePl;

		public VBloodTeacher Teacher;

		public float WeaponLevel;

		public List<ItemCost> Cost;

		public int QualityPoints => GearBalance.Current.RodQualityOf(Tier);

		public string NameIn(string language)
		{
			if (!(language == "pl"))
			{
				return Name;
			}
			return NamePl;
		}
	}
	public static class RodCatalog
	{
		public const string BaseItem = "Item_Weapon_FishingPole_T01";

		public const string ItemPrefix = "Item_Weapon_DeepRising_FishingPole_T0";

		private const string FishPrefix = "Item_Ingredient_Fish_DeepRising_";

		private const int OneRod = 1;

		public static readonly RodItem[] All = new RodItem[3]
		{
			new RodItem
			{
				Tier = 2,
				Item = "Item_Weapon_DeepRising_FishingPole_T02",
				Name = "Iron Fishing Pole",
				NamePl = "Żelazna wędka",
				Teacher = VBloodTeachers.Quincey,
				WeaponLevel = 50f,
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Weapon_FishingPole_T01",
						DisplayName = "Fishing Pole",
						DisplayNamePl = "Wędka",
						Amount = 1
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Mineral_IronBar",
						DisplayName = "Iron Ingot",
						DisplayNamePl = "Sztabka żelaza",
						Amount = 8
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Plank",
						DisplayName = "Plank",
						DisplayNamePl = "Deska",
						Amount = 8
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Thread_Coarse",
						DisplayName = "Coarse Thread",
						DisplayNamePl = "Szorstka nić",
						Amount = 8
					}
				}
			},
			new RodItem
			{
				Tier = 3,
				Item = "Item_Weapon_DeepRising_FishingPole_T03",
				Name = "Silk Fishing Pole",
				NamePl = "Jedwabna wędka",
				Teacher = VBloodTeachers.Ungora,
				WeaponLevel = 70f,
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Weapon_DeepRising_FishingPole_T02",
						DisplayName = "Iron Fishing Pole",
						DisplayNamePl = "Żelazna wędka",
						Amount = 1
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Silk",
						DisplayName = "Silk",
						DisplayNamePl = "Jedwab",
						Amount = 8
					},
					new ItemCost
					{
						Item = "Item_Ingredient_ReinforcedPlank",
						DisplayName = "Reinforced Plank",
						DisplayNamePl = "Wzmocniona deska",
						Amount = 8
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Fish_DeepRising_GravetoothPike",
						DisplayName = "Gravetooth Pike",
						DisplayNamePl = "Szczupak grobozęby",
						Amount = 3
					}
				}
			},
			new RodItem
			{
				Tier = 4,
				Item = "Item_Weapon_DeepRising_FishingPole_T04",
				Name = "Blood Fishing Pole",
				NamePl = "Krwawa wędka",
				Teacher = VBloodTeachers.Baron,
				WeaponLevel = 85f,
				Cost = new List<ItemCost>
				{
					new ItemCost
					{
						Item = "Item_Weapon_DeepRising_FishingPole_T03",
						DisplayName = "Silk Fishing Pole",
						DisplayNamePl = "Jedwabna wędka",
						Amount = 1
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Mineral_DarkSilverBar",
						DisplayName = "Dark Silver Ingot",
						DisplayNamePl = "Sztabka ciemnego srebra",
						Amount = 2
					},
					new ItemCost
					{
						Item = "Item_BloodEssence_T03_Primal",
						DisplayName = "Primal Blood Essence",
						DisplayNamePl = "Pierwotna esencja krwi",
						Amount = 1
					},
					new ItemCost
					{
						Item = "Item_Ingredient_Fish_DeepRising_EclipseKoi",
						DisplayName = "Eclipse Koi",
						DisplayNamePl = "Koi zaćmienia",
						Amount = 4
					}
				}
			}
		};

		public static RodItem Find(int tier)
		{
			RodItem[] all = All;
			foreach (RodItem rodItem in all)
			{
				if (rodItem.Tier == tier)
				{
					return rodItem;
				}
			}
			return null;
		}

		public static int TierOf(string item)
		{
			if (string.Equals(item, "Item_Weapon_FishingPole_T01", StringComparison.OrdinalIgnoreCase))
			{
				return 1;
			}
			RodItem[] all = All;
			foreach (RodItem rodItem in all)
			{
				if (string.Equals(rodItem.Item, item, StringComparison.OrdinalIgnoreCase))
				{
					return rodItem.Tier;
				}
			}
			return 0;
		}

		public static int QualityPointsOf(int tier)
		{
			return Find(tier)?.QualityPoints ?? 0;
		}
	}
	public sealed class LevelReward
	{
		public int Level;

		public string Text;

		public string TextPl;

		public string TextIn(string language)
		{
			if (!(language == "pl"))
			{
				return Text;
			}
			return TextPl;
		}
	}
	public static class LevelRewards
	{
		private const float PercentPerUnit = 100f;

		private static int LongerByPercent => (int)Math.Round((Progression.Levels.LongerReactionFactor - 1f) * 100f);

		public static List<LevelReward> All()
		{
			List<LevelReward> list = new List<LevelReward>();
			list.Add(new LevelReward
			{
				Level = Progression.Levels.LongerReactionLevel,
				Text = $"{LongerByPercent}% more time to hook a bite",
				TextPl = $"{LongerByPercent}% więcej czasu na zacięcie"
			});
			list.Add(new LevelReward
			{
				Level = Progression.Levels.EasierPerfectLevel,
				Text = $"A Perfect catch from quality {Progression.Levels.EasierPerfectThreshold}",
				TextPl = $"Perfekcyjny połów już od jakości {Progression.Levels.EasierPerfectThreshold}"
			});
			if (SchoolBalance.Current.Enabled)
			{
				list.Add(new LevelReward
				{
					Level = SchoolBalance.Current.MapLevel,
					Text = "The roaming school of fish shows on the map when it comes",
					TextPl = "Wędrującą ławicę widać na mapie, gdy przyjdzie"
				});
			}
			list.Add(new LevelReward
			{
				Level = DeepMonsterBalance.Current.AnglerLevel,
				Text = "Monsters from the deep come up in place of a catch now and then, each region its own, and tainted bait draws them",
				TextPl = "Zamiast połowu wychodzą czasem potwory z głębin, w każdym regionie inne, a skażona przynęta je wabi"
			});
			list.Add(new LevelReward
			{
				Level = Progression.Levels.WaterSenseLevel,
				Text = "The map outlines deep and silver water, and by the bait slot you read what water you stand at",
				TextPl = "Mapa pokazuje głęboką i srebrną wodę, a nad slotem przynęty widać, przy jakiej wodzie stoisz"
			});
			list.Add(new LevelReward
			{
				Level = Progression.Levels.LegendaryNewsLevel,
				Text = "You are told when and where a legendary spot rises, and the map shows where to look for it",
				TextPl = "Dostajesz wieści o legendarnych łowiskach, a mapa pokazuje, gdzie ich szukać"
			});
			list.Sort((LevelReward a, LevelReward b) => a.Level.CompareTo(b.Level));
			return list;
		}
	}
	public static class BaitRules
	{
		public const float NoChange = 1f;

		public const float MinBiteTimeMultiplier = 0.1f;

		public const float MaxRarityShift = 1f;

		public const int SpentPerCast = 1;
	}
	public sealed class BaitDefinition
	{
		public string Id { get; set; }

		public string DisplayName { get; set; }

		public string Item { get; set; }

		public string Description { get; set; }

		public string DisplayNamePl { get; set; }

		public string DescriptionPl { get; set; }

		public float BiteTimeMultiplier { get; set; } = 1f;

		public float NightBiteTimeMultiplier { get; set; } = 1f;

		public int QualityPoints { get; set; }

		public float RarityShift { get; set; }

		public List<string> Attracts { get; set; } = new List<string>();

		public float AttractMultiplier { get; set; } = 1f;

		public float MonsterChanceMultiplier { get; set; } = 1f;

		public float MonsterLootMultiplier { get; set; } = 1f;

		public bool NeedsMonsterLevel { get; set; }

		public string Label
		{
			get
			{
				if (!string.IsNullOrEmpty(DisplayName))
				{
					return DisplayName;
				}
				return Id;
			}
		}

		public string LabelIn(string language)
		{
			if (!(language == "pl") || string.IsNullOrEmpty(DisplayNamePl))
			{
				return Label;
			}
			return DisplayNamePl;
		}

		public string DescriptionIn(string language)
		{
			if (!(language == "pl") || string.IsNullOrEmpty(DescriptionPl))
			{
				return Description;
			}
			return DescriptionPl;
		}

		public float BiteTimeMultiplierAt(bool isNight)
		{
			return BiteTimeMultiplier * (isNight ? NightBiteTimeMultiplier : 1f);
		}

		public bool AttractsFish(string fishId)
		{
			foreach (string item in Attracts ?? new List<string>())
			{
				if (string.Equals(item, fishId, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}
	}
	public sealed class BaitFile
	{
		public const int CurrentSchemaVersion = 1;

		public int SchemaVersion { get; set; }

		public List<BaitDefinition> Baits { get; set; } = new List<BaitDefinition>();

		public BaitDefinition Find(string id)
		{
			foreach (BaitDefinition bait in Baits)
			{
				if (string.Equals(bait.Id, id, StringComparison.OrdinalIgnoreCase))
				{
					return bait;
				}
			}
			return null;
		}
	}
	public static class BaitLoader
	{
		public static BaitFile Parse(string json)
		{
			return JsonFiles.Parse<BaitFile>(json) ?? new BaitFile();
		}
	}
	public static class BaitValidator
	{
		public static List<string> Validate(BaitFile file, Func<string, bool> itemExists = null, Func<string, bool> fishExists = null)
		{
			List<string> list = new List<string>();
			if (file.SchemaVersion != 1)
			{
				list.Add($"schemaVersion is {file.SchemaVersion}, expected {1}");
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			HashSet<string> hashSet2 = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (BaitDefinition item in file.Baits ?? new List<BaitDefinition>())
			{
				string text = "bait '" + item.Id + "'";
				if (string.IsNullOrWhiteSpace(item.Id))
				{
					list.Add("a bait has no id");
				}
				else if (!hashSet.Add(item.Id))
				{
					list.Add(text + ": duplicate id");
				}
				if (string.IsNullOrWhiteSpace(item.Item))
				{
					list.Add(text + ": no item");
				}
				else if (!hashSet2.Add(item.Item))
				{
					list.Add(text + ": item '" + item.Item + "' is already another bait");
				}
				else if (itemExists != null && !itemExists(item.Item))
				{
					list.Add(text + ": unknown item prefab '" + item.Item + "'");
				}
				if (item.BiteTimeMultiplier < 0.1f || item.NightBiteTimeMultiplier < 0.1f)
				{
					list.Add($"{text}: bite time multipliers must be at least {0.1f}");
				}
				if (item.RarityShift < 0f || item.RarityShift > 1f)
				{
					list.Add($"{text}: rarityShift must be between 0 and {1f}");
				}
				if (item.AttractMultiplier < 1f)
				{
					list.Add($"{text}: attractMultiplier must be at least {1f}");
				}
				if (item.MonsterChanceMultiplier < 0f || item.MonsterLootMultiplier < 0f)
				{
					list.Add(text + ": monsterChanceMultiplier and monsterLootMultiplier cannot be negative");
				}
				foreach (string item2 in item.Attracts ?? new List<string>())
				{
					if (fishExists != null && !fishExists(item2))
					{
						list.Add(text + ": attracts unknown fish '" + item2 + "'");
					}
				}
			}
			return list;
		}
	}
	public static class BalanceDefaults
	{
		public const float BaseFishChance = 0.75f;

		public const float WeakCatchJunkChance = 0.15f;

		public const float PerfectReactionSeconds = 0.35f;

		public const float MaxReactionSeconds = 1.2f;

		public const float MinBiteDelaySeconds = 4f;

		public const float MaxBiteDelaySeconds = 12f;

		public const int SpotCatches = 5;

		public const float SpotRespawnSeconds = 3f;

		public const float PlacedSpotRestSeconds = 720f;

		public const int LegendarySpotIntervalMinutes = 120;

		public const int LegendarySpotDurationMinutes = 30;

		public const int LegendaryAnnounceMinutes = 5;

		public const int LegendarySearchRadius = 160;

		public const int HookAccuracyMaxPoints = 60;

		public const int StreakPointsPerCatch = 2;

		public const int StreakMaxPoints = 10;

		public const int PerfectCatchThreshold = 90;
	}
	public static class QualityRules
	{
		public const float FullHookAccuracy = 1f;

		public const int MinQuality = 1;

		public const int MaxQuality = 100;

		public const int GoodCatchThreshold = 50;

		public const int ExcellentCatchThreshold = 75;

		public const float GoodRarityShift = 0.02f;

		public const float ExcellentRarityShift = 0.05f;

		public const float PerfectRarityShift = 0.1f;

		public const int BaseFishCount = 1;

		public const int PerfectFishCount = 2;

		public const float ExcellentSecondFishChance = 0.25f;

		public const float WeakXpMultiplier = 0.75f;

		public const float GoodXpMultiplier = 1f;

		public const float ExcellentXpMultiplier = 1.25f;

		public const float PerfectXpMultiplier = 1.5f;

		public const float UncommonShiftParts = 2f;

		public const float RareShiftParts = 1f;
	}
	public sealed class FishingBalance
	{
		public float BaseFishChance = 0.75f;

		public float WeakCatchJunkChance = 0.15f;

		public float PerfectReactionSeconds = 0.35f;

		public float MaxReactionSeconds = 1.2f;

		public float MinBiteDelaySeconds = 4f;

		public float MaxBiteDelaySeconds = 12f;

		public int HookAccuracyMaxPoints = 60;

		public int StreakPointsPerCatch = 2;

		public int StreakMaxPoints = 10;

		public int PerfectCatchThreshold = 90;

		public FishingBalance Clone()
		{
			return (FishingBalance)MemberwiseClone();
		}
	}
	public static class BloodQualityRules
	{
		public const float MaxQuality = 100f;

		public const float PointsPerUnit = 100f;

		public static readonly float[] TierThresholds = new float[5] { 1f, 30f, 60f, 90f, 100f };

		public const float RareFishBonus = 1f;

		public const float RareFishCap = 94f;

		public const float LegendaryFishBonus = 5f;

		public const float LegendaryFishCap = 100f;

		public static float AfterRareFish(float current)
		{
			float num = 94f;
			float[] tierThresholds = TierThresholds;
			foreach (float num2 in tierThresholds)
			{
				if (num2 > current)
				{
					num = Math.Min(num, num2 - 1f);
					break;
				}
			}
			return Math.Max(current, Math.Min(current + 1f, num));
		}

		public static float AfterLegendaryFish(float current)
		{
			return Math.Max(current, Math.Min(current + 5f, 100f));
		}
	}
	public static class PrisonerEffectRules
	{
		public const int Drawings = 8;

		public const float SturgeonDrainHealthFactor = 0.5f;

		public const float VoltfangDrainHealthFactor = 0f;

		public const float FullDrainHealthFactor = 1f;

		public static float HealthAfterLoss(float before, float after, float factor)
		{
			if (after >= before)
			{
				return after;
			}
			return before - (before - after) * Math.Clamp(factor, 0f, 1f);
		}
	}
	public static class CatchabilityAudit
	{
		public const int BestRodTier = 4;

		public static List<string> Run(LootTableFile file, Func<BiomeTable, IEnumerable<WaterType>> watersOf)
		{
			List<string> list = new List<string>();
			if (file?.Biomes == null)
			{
				return list;
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (BiomeTable biome in file.Biomes)
			{
				List<WaterType> list2 = new List<WaterType>(watersOf(biome) ?? new List<WaterType>());
				foreach (LootEntry item in biome.Fish ?? new List<LootEntry>())
				{
					string text = item.Id + " in " + biome.Biome;
					bool flag = false;
					if (list2.Count == 0)
					{
						list.Add(text + ": the region has no fishing spots at all");
						flag = true;
					}
					else if (!HasWaterFor(list2, item.Water))
					{
						list.Add($"{text}: needs {item.Water} water, and the region has none");
						flag = true;
					}
					if (item.MinRodTier > 4)
					{
						list.Add($"{text}: needs a rod of tier {item.MinRodTier}, and the best there is has tier {4}");
						flag = true;
					}
					if (item.Rarity != FishRarity.Legendary)
					{
						if (item.Weight <= 0f)
						{
							list.Add(text + ": its weight is 0");
							flag = true;
						}
						if (biome.RarityChances == null || !biome.RarityChances.TryGetValue(item.Rarity, out var value) || value <= 0f)
						{
							list.Add($"{text}: the region gives {item.Rarity} fish no chance");
							flag = true;
						}
						if (!flag)
						{
							hashSet.Add(item.Item);
						}
					}
				}
			}
			foreach (BiomeTable biome2 in file.Biomes)
			{
				foreach (LootEntry item2 in biome2.Fish ?? new List<LootEntry>())
				{
					if (item2.Rarity == FishRarity.Legendary && !string.IsNullOrEmpty(item2.Bait) && !hashSet.Contains(item2.Bait))
					{
						list.Add($"{item2.Id} in {biome2.Biome}: its bait {item2.Bait} is no fish that can be caught");
					}
				}
			}
			return list;
		}

		private static bool HasWaterFor(List<WaterType> waters, WaterNeed need)
		{
			foreach (WaterType item in waters)
			{
				if (WaterRules.Satisfies(item, need))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class CatchNeeds
	{
		private const string Separator = "; ";

		public static string Describe(LootEntry fish, LootTableFile tables, string language)
		{
			bool flag = language == "pl";
			List<string> list = new List<string>();
			if (fish.Rarity == FishRarity.Legendary)
			{
				list.Add(flag ? "legendarne łowisko" : "a legendary spot");
			}
			string text = WaterRules.NameOf(fish.Water, language);
			if (text.Length > 0)
			{
				list.Add(text);
			}
			if (fish.Time == CatchTime.Night)
			{
				list.Add(flag ? "tylko nocą" : "only at night");
			}
			if (fish.Time == CatchTime.Day)
			{
				list.Add(flag ? "tylko za dnia" : "only by day");
			}
			if (fish.MinRodTier > 1)
			{
				string text2 = RodCatalog.Find(fish.MinRodTier)?.NameIn(language) ?? (flag ? $"wędka poziomu {fish.MinRodTier}" : $"a rod of tier {fish.MinRodTier}");
				bool flag2 = fish.MinRodTier >= 4;
				list.Add(flag2 ? text2 : (text2 + (flag ? " lub lepsza" : " or better")));
			}
			if (fish.Rarity == FishRarity.Legendary)
			{
				if (!string.IsNullOrEmpty(fish.Bait))
				{
					list.Add((flag ? "przynęta: " : "bait: ") + NameOfItem(fish.Bait, tables, language));
				}
				if (fish.BloodMoon)
				{
					list.Add(flag ? "Krwawy Księżyc" : "a Blood Moon");
				}
				if (fish.FullStreak)
				{
					list.Add(flag ? "pełna seria połowów" : "a full streak of catches");
				}
				if (fish.MinQuality > 0)
				{
					list.Add(flag ? $"jakość połowu od {fish.MinQuality}" : $"catch quality {fish.MinQuality} or more");
				}
				if (fish.Fight != null)
				{
					list.Add(flag ? "walka o rybę" : "a fight for the fish");
				}
				if (fish.Radiation != null)
				{
					list.Add(flag ? "łowisko razi świętym promieniowaniem" : "the spot burns with holy radiation");
				}
			}
			FishHaul haul = fish.Haul;
			if (haul != null)
			{
				list.Add(flag ? ("hol: gra napięcia żyłki przy łowisku" + ((haul.MinHealthPercent > 0) ? $", zdrowie nie niżej niż {haul.MinHealthPercent}%" : string.Empty)) : ("a haul: the game of the line's tension by the spot" + ((haul.MinHealthPercent > 0) ? $", health not under {haul.MinHealthPercent}%" : string.Empty)));
			}
			return string.Join("; ", list);
		}

		private static string NameOfItem(string item, LootTableFile tables, string language)
		{
			foreach (BiomeTable item2 in tables?.Biomes ?? new List<BiomeTable>())
			{
				foreach (LootEntry item3 in item2.Fish ?? new List<LootEntry>())
				{
					if (string.Equals(item3.Item, item, StringComparison.OrdinalIgnoreCase))
					{
						if (language == "pl" && !string.IsNullOrEmpty(item3.DisplayNamePl))
						{
							return item3.DisplayNamePl;
						}
						return string.IsNullOrEmpty(item3.DisplayName) ? item3.Id : item3.DisplayName;
					}
				}
			}
			return item;
		}
	}
	public interface IRandomSource
	{
		double NextDouble();
	}
	public sealed class SystemRandomSource : IRandomSource
	{
		private readonly Random _random;

		public SystemRandomSource()
		{
			_random = new Random();
		}

		public SystemRandomSource(int seed)
		{
			_random = new Random(seed);
		}

		public double NextDouble()
		{
			return _random.NextDouble();
		}
	}
	public enum CatchOutcome
	{
		Escaped,
		Junk,
		Fish
	}
	public sealed class CatchResult
	{
		public CatchOutcome Outcome;

		public int Quality;

		public CatchGrade Grade;

		public LootEntry Entry;

		public int Count;

		public LootEntry LegendaryAttempt;

		public static CatchResult Escaped()
		{
			return new CatchResult
			{
				Outcome = CatchOutcome.Escaped
			};
		}
	}
	public static class CatchRoller
	{
		private static readonly FishRarity[] RolledRarities = new FishRarity[3]
		{
			FishRarity.Common,
			FishRarity.Uncommon,
			FishRarity.Rare
		};

		public static float RollBiteDelay(FishingBalance balance, IRandomSource random, BaitDefinition bait, bool isNight)
		{
			float num = RollBiteDelay(balance, random);
			if (bait != null)
			{
				return num * bait.BiteTimeMultiplierAt(isNight);
			}
			return num;
		}

		public static float RollBiteDelay(FishingBalance balance, IRandomSource random)
		{
			float num = Math.Min(balance.MinBiteDelaySeconds, balance.MaxBiteDelaySeconds);
			float num2 = Math.Max(balance.MinBiteDelaySeconds, balance.MaxBiteDelaySeconds);
			return num + (float)random.NextDouble() * (num2 - num);
		}

		public static CatchResult Roll(BiomeTable table, int quality, FishingBalance balance, IRandomSource random)
		{
			return Roll(table, quality, balance, random, CatchContext.Unrestricted(isNight: false), allTimes: true);
		}

		public static CatchResult Roll(BiomeTable table, int quality, FishingBalance balance, IRandomSource random, CatchContext context)
		{
			return Roll(table, quality, balance, random, context, allTimes: false);
		}

		private static CatchResult Roll(BiomeTable table, int quality, FishingBalance balance, IRandomSource random, CatchContext context, bool allTimes)
		{
			CatchGrade catchGrade = QualityCalculator.GradeOf(quality, balance);
			CatchResult catchResult = new CatchResult
			{
				Quality = quality,
				Grade = catchGrade,
				Count = 1
			};
			foreach (LootEntry item in table.Fish)
			{
				if (item.IsLegendaryAttempt(context, quality))
				{
					catchResult.LegendaryAttempt = item;
					if (random.NextDouble() >= (double)item.Chance)
					{
						break;
					}
					catchResult.Outcome = CatchOutcome.Fish;
					catchResult.Entry = item;
					catchResult.Count = 1;
					return catchResult;
				}
			}
			List<LootEntry> list = new List<LootEntry>();
			foreach (LootEntry item2 in table.Fish)
			{
				if (item2.Rarity != FishRarity.Legendary && (allTimes ? (context.RodTier >= item2.MinRodTier) : item2.IsAvailable(context)))
				{
					list.Add(item2);
				}
			}
			if (random.NextDouble() >= (double)balance.BaseFishChance || (catchGrade == CatchGrade.Weak && random.NextDouble() < (double)balance.WeakCatchJunkChance) || TotalWeight(list) <= 0f)
			{
				catchResult.Outcome = CatchOutcome.Junk;
				catchResult.Entry = PickWeighted(table.Junk, null, random);
				catchResult.Count = catchResult.Entry.Quantity;
				return catchResult;
			}
			LootEntry lootEntry = ((context.Bait == null) ? null : PickAttracted(table, list, context.Bait, catchGrade, context.RarityShift, random));
			float shift = QualityCalculator.RarityShiftOf(catchGrade) + (context.Bait?.RarityShift ?? 0f) + context.RarityShift;
			FishRarity value = PickRarity(ShiftedRarityChances(table.RarityChances, list, shift), random);
			catchResult.Outcome = CatchOutcome.Fish;
			catchResult.Entry = lootEntry ?? PickWeighted(list, value, random) ?? PickWeighted(list, null, random);
			switch (catchGrade)
			{
			case CatchGrade.Perfect:
				catchResult.Count = 2;
				break;
			case CatchGrade.Excellent:
				if (random.NextDouble() < 0.25)
				{
					catchResult.Count++;
				}
				break;
			}
			return catchResult;
		}

		private static LootEntry PickAttracted(BiomeTable table, List<LootEntry> fish, BaitDefinition bait, CatchGrade grade, float placeShift, IRandomSource random)
		{
			if (bait.AttractMultiplier <= 1f)
			{
				return null;
			}
			List<LootEntry> list = new List<LootEntry>();
			foreach (LootEntry item in fish)
			{
				if (bait.AttractsFish(item.Id) && item.Weight > 0f)
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			Dictionary<FishRarity, float> dictionary = ShiftedRarityChances(table.RarityChances, fish, QualityCalculator.RarityShiftOf(grade) + bait.RarityShift + placeShift);
			double num = random.NextDouble();
			foreach (LootEntry item2 in list)
			{
				float num2 = dictionary[item2.Rarity] * item2.Weight / TotalWeight(fish, item2.Rarity) * (bait.AttractMultiplier - 1f);
				if (num < (double)num2)
				{
					return item2;
				}
				num -= (double)num2;
			}
			return null;
		}

		public static Dictionary<FishRarity, float> ShiftedRarityChances(BiomeTable table, float shift)
		{
			return ShiftedRarityChances(table.RarityChances, table.Fish, shift);
		}

		public static Dictionary<FishRarity, float> ShiftedRarityChances(Dictionary<FishRarity, float> baseChances, List<LootEntry> fish, float shift)
		{
			Dictionary<FishRarity, float> dictionary = new Dictionary<FishRarity, float>();
			FishRarity[] rolledRarities = RolledRarities;
			foreach (FishRarity fishRarity in rolledRarities)
			{
				dictionary[fishRarity] = ((TotalWeight(fish, fishRarity) > 0f && baseChances.TryGetValue(fishRarity, out var value)) ? value : 0f);
			}
			float num = ((TotalWeight(fish, FishRarity.Uncommon) > 0f) ? 2f : 0f);
			float num2 = ((TotalWeight(fish, FishRarity.Rare) > 0f) ? 1f : 0f);
			float num3 = num + num2;
			if (num3 <= 0f)
			{
				return dictionary;
			}
			float num4 = Math.Min(Math.Max(shift, 0f), dictionary[FishRarity.Common]);
			dictionary[FishRarity.Common] -= num4;
			dictionary[FishRarity.Uncommon] += num4 * num / num3;
			dictionary[FishRarity.Rare] += num4 * num2 / num3;
			return dictionary;
		}

		public static float TotalWeight(List<LootEntry> entries, FishRarity? rarity = null)
		{
			float num = 0f;
			if (entries == null)
			{
				return num;
			}
			foreach (LootEntry entry in entries)
			{
				if ((!rarity.HasValue || entry.Rarity == rarity) && entry.Weight > 0f)
				{
					num += entry.Weight;
				}
			}
			return num;
		}

		private static FishRarity PickRarity(Dictionary<FishRarity, float> chances, IRandomSource random)
		{
			float num = 0f;
			FishRarity[] rolledRarities = RolledRarities;
			foreach (FishRarity key in rolledRarities)
			{
				num += chances[key];
			}
			double num2 = random.NextDouble() * (double)num;
			rolledRarities = RolledRarities;
			foreach (FishRarity fishRarity in rolledRarities)
			{
				num2 -= (double)chances[fishRarity];
				if (num2 < 0.0)
				{
					return fishRarity;
				}
			}
			return FishRarity.Common;
		}

		private static LootEntry PickWeighted(List<LootEntry> entries, FishRarity? rarity, IRandomSource random)
		{
			double num = random.NextDouble() * (double)TotalWeight(entries, rarity);
			LootEntry result = null;
			foreach (LootEntry entry in entries)
			{
				if ((!rarity.HasValue || entry.Rarity == rarity) && !(entry.Weight <= 0f))
				{
					result = entry;
					num -= (double)entry.Weight;
					if (num < 0.0)
					{
						return entry;
					}
				}
			}
			return result;
		}
	}
	public sealed class CodexEntry
	{
		public int Catches { get; set; }

		public int BestQuality { get; set; }

		public string FirstCaught { get; set; }
	}
	public sealed class Trophy
	{
		public string Fish { get; set; }

		public int Quality { get; set; }

		public string Date { get; set; }

		public string Biome { get; set; }
	}
	public static class CodexDefaults
	{
		public const int BiomeBonusPoints = 5;
	}
	public static class CodexRules
	{
		public const string DateFormat = "yyyy-MM-dd";

		private const FishRarity LastRarityWithoutTrophies = FishRarity.Uncommon;

		public static bool Record(IDictionary<string, CodexEntry> codex, string fishId, int quality, DateTime day)
		{
			CodexEntry value;
			bool num = !codex.TryGetValue(fishId, out value);
			if (num)
			{
				CodexEntry obj = new CodexEntry
				{
					FirstCaught = day.ToString("yyyy-MM-dd")
				};
				value = obj;
				codex[fishId] = obj;
			}
			value.Catches++;
			value.BestQuality = Math.Max(value.BestQuality, quality);
			return num;
		}

		public static int KnownIn(BiomeTable table, IDictionary<string, CodexEntry> codex, out int total)
		{
			total = 0;
			int num = 0;
			if (table == null)
			{
				return num;
			}
			foreach (LootEntry item in table.Fish)
			{
				total++;
				if (codex != null && codex.ContainsKey(item.Id))
				{
					num++;
				}
			}
			return num;
		}

		public static bool IsComplete(BiomeTable table, IDictionary<string, CodexEntry> codex)
		{
			if (table == null || codex == null)
			{
				return false;
			}
			int num = 0;
			foreach (LootEntry item in table.Fish)
			{
				if (item.Rarity != FishRarity.Legendary)
				{
					num++;
					if (!codex.ContainsKey(item.Id))
					{
						return false;
					}
				}
			}
			return num > 0;
		}

		public static bool IsTrophy(CatchResult result)
		{
			if (result.Outcome == CatchOutcome.Fish && result.Grade == CatchGrade.Perfect)
			{
				return result.Entry.Rarity > FishRarity.Uncommon;
			}
			return false;
		}

		public static bool TryAddTrophy(List<Trophy> trophies, Trophy trophy)
		{
			for (int i = 0; i < trophies.Count; i++)
			{
				if (string.Equals(trophies[i].Fish, trophy.Fish, StringComparison.OrdinalIgnoreCase))
				{
					if (trophies[i].Quality >= trophy.Quality)
					{
						return false;
					}
					trophies[i] = trophy;
					return true;
				}
			}
			trophies.Add(trophy);
			return true;
		}
	}
	public static class DeepMonsterDefaults
	{
		public const float Chance = 0.03f;

		public const int AnglerLevel = 80;

		public const int Xp = 250;

		public const float Seconds = 120f;

		public const float Certain = 1f;
	}
	public sealed class DeepMonsterBalance
	{
		public float Chance = 0.03f;

		public int AnglerLevel = 80;

		public int Xp = 250;

		public static DeepMonsterBalance Current = new DeepMonsterBalance();
	}
	public sealed class MonsterLoot
	{
		public string Item { get; set; }

		public string DisplayName { get; set; }

		public string DisplayNamePl { get; set; }

		public int Min { get; set; } = 1;

		public int Max { get; set; } = 1;

		public float Chance { get; set; } = 1f;

		public string NameIn(string language)
		{
			if (!(language == "pl") || string.IsNullOrEmpty(DisplayNamePl))
			{
				if (!string.IsNullOrEmpty(DisplayName))
				{
					return DisplayName;
				}
				return Item;
			}
			return DisplayNamePl;
		}
	}
	public sealed class DeepMonsterGroup
	{
		public string Id { get; set; }

		public string DisplayName { get; set; }

		public string DisplayNamePl { get; set; }

		public float Weight { get; set; } = 1f;

		public float Seconds { get; set; } = 120f;

		public List<FightMonster> Monsters { get; set; } = new List<FightMonster>();

		public List<MonsterLoot> Loot { get; set; } = new List<MonsterLoot>();

		public string NameIn(string language)
		{
			if (!(language == "pl") || string.IsNullOrEmpty(DisplayNamePl))
			{
				if (!string.IsNullOrEmpty(DisplayName))
				{
					return DisplayName;
				}
				return Id;
			}
			return DisplayNamePl;
		}
	}
	public struct LootGrant
	{
		public MonsterLoot Loot;

		public int Amount;
	}
	public static class DeepMonsterRules
	{
		public static float ChanceFor(DeepMonsterBalance balance, BiomeTable table, BaitDefinition bait, int anglerLevel)
		{
			if (table?.DeepMonsters == null || table.DeepMonsters.Count == 0)
			{
				return 0f;
			}
			if (anglerLevel < balance.AnglerLevel)
			{
				return 0f;
			}
			return Math.Clamp(balance.Chance * (bait?.MonsterChanceMultiplier ?? 1f), 0f, 1f);
		}

		public static DeepMonsterGroup Pick(List<DeepMonsterGroup> groups, IRandomSource random)
		{
			float num = 0f;
			foreach (DeepMonsterGroup item in groups ?? new List<DeepMonsterGroup>())
			{
				num += Math.Max(0f, item.Weight);
			}
			if (num <= 0f)
			{
				return null;
			}
			double num2 = random.NextDouble() * (double)num;
			DeepMonsterGroup result = null;
			foreach (DeepMonsterGroup group in groups)
			{
				if (!(group.Weight <= 0f))
				{
					result = group;
					num2 -= (double)group.Weight;
					if (num2 < 0.0)
					{
						return group;
					}
				}
			}
			return result;
		}

		public static List<LootGrant> RollLoot(DeepMonsterGroup group, float lootMultiplier, IRandomSource random)
		{
			List<LootGrant> list = new List<LootGrant>();
			foreach (MonsterLoot item in group.Loot ?? new List<MonsterLoot>())
			{
				if (!(random.NextDouble() >= (double)item.Chance))
				{
					int num = Math.Max(0, item.Max - item.Min);
					int val = item.Min + (int)Math.Floor(random.NextDouble() * (double)(num + 1));
					val = (int)Math.Round((float)Math.Min(val, item.Max) * Math.Max(0f, lootMultiplier));
					if (val > 0)
					{
						list.Add(new LootGrant
						{
							Loot = item,
							Amount = val
						});
					}
				}
			}
			return list;
		}
	}
	public static class GearDefaults
	{
		public const int BrewTiers = 3;

		public const int RodTiers = 3;

		public const int FirstRodTier = 2;

		public const float ImmunityPoints = 1000f;

		public const string BrewDurationMinutes = "30, 60, 120";

		public const string BrewEssenceAmount = "30, 60, 100";

		public const string BrewYieldBonus = "0.1, 0.2, 0.3";

		public const string BrewBloodDrainReduction = "0.1, 0.2, 0.3";

		public const string BrewSunResistance = "25, 50, 75";

		public const string BrewHolyResistance = "25, 50, 100";

		public const string BrewGarlicResistance = "25, 50, 1000";

		public const string BrewPowerBonus = "0.05, 0.1, 0.15";

		public const float SealYieldBonus = 0.05f;

		public const float SealBloodDrainReduction = 0.05f;

		public const float SealResistance = 10f;

		public const float SealPowerBonus = 0.03f;

		public const float SealSetMultiplier = 1.5f;

		public const string RodQualityPoints = "5, 10, 15";

		public const float ReelBiteDelayFactor = 0.7f;

		public const float ReelHaulFactor = 0.7f;

		public const float FloatReactionFactor = 1.15f;

		public const float MagnetJunkFactor = 2f;
	}
	public sealed class GearBalance
	{
		public float[] BrewDurationMinutes = Parse("30, 60, 120", 3);

		public float[] BrewEssenceAmount = Parse("30, 60, 100", 3);

		public float[] BrewYieldBonus = Parse("0.1, 0.2, 0.3", 3);

		public float[] BrewBloodDrainReduction = Parse("0.1, 0.2, 0.3", 3);

		public float[] BrewSunResistance = Parse("25, 50, 75", 3);

		public float[] BrewHolyResistance = Parse("25, 50, 100", 3);

		public float[] BrewGarlicResistance = Parse("25, 50, 1000", 3);

		public float[] BrewPowerBonus = Parse("0.05, 0.1, 0.15", 3);

		public float SealYieldBonus = 0.05f;

		public float SealBloodDrainReduction = 0.05f;

		public float SealResistance = 10f;

		public float SealPowerBonus = 0.03f;

		public float SealSetMultiplier = 1.5f;

		public float[] RodQualityPoints = Parse("5, 10, 15", 3);

		public float ReelBiteDelayFactor = 0.7f;

		public float ReelHaulFactor = 0.7f;

		public float FloatReactionFactor = 1.15f;

		public float MagnetJunkFactor = 2f;

		public static GearBalance Current = new GearBalance();

		private const char ValueSeparator = ',';

		private const string NumberFormat = "0.####";

		private const char WordSeparator = ' ';

		private const char NameSeparator = '=';

		private const string DurationName = "bd";

		private const string EssenceName = "be";

		private const string YieldName = "by";

		private const string BloodDrainName = "bb";

		private const string SunName = "bs";

		private const string HolyName = "bh";

		private const string GarlicName = "bg";

		private const string PowerName = "bp";

		private const string SealYieldName = "sy";

		private const string SealBloodDrainName = "sb";

		private const string SealResistanceName = "sr";

		private const string SealPowerName = "sp";

		private const string SealSetName = "ss";

		private const string RodQualityName = "rq";

		private const string ReelName = "ar";

		private const string ReelHaulName = "ah";

		private const string FloatName = "af";

		private const string MagnetName = "am";

		public int RodQualityOf(int tier)
		{
			int num = tier - 2;
			if (num < 0 || num >= RodQualityPoints.Length)
			{
				return 0;
			}
			return (int)Math.Round(RodQualityPoints[num]);
		}

		public static bool TryParse(string text, int count, out float[] values)
		{
			values = null;
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string[] array = text.Split(',');
			if (array.Length != count)
			{
				return false;
			}
			float[] array2 = new float[count];
			for (int i = 0; i < count; i++)
			{
				if (!float.TryParse(array[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out array2[i]) || float.IsNaN(array2[i]) || float.IsInfinity(array2[i]) || array2[i] < 0f)
				{
					return false;
				}
			}
			values = array2;
			return true;
		}

		private static float[] Parse(string text, int count)
		{
			if (!TryParse(text, count, out var values))
			{
				throw new FormatException($"'{text}' is not {count} numbers");
			}
			return values;
		}

		private static string Format(float value)
		{
			return value.ToString("0.####", CultureInfo.InvariantCulture);
		}

		private static string Format(float[] values)
		{
			string[] array = new string[values.Length];
			for (int i = 0; i < values.Length; i++)
			{
				array[i] = Format(values[i]);
			}
			return string.Join(','.ToString(), array);
		}

		public string ToWire()
		{
			List<string> words = new List<string>();
			Add("bd", Format(BrewDurationMinutes));
			Add("be", Format(BrewEssenceAmount));
			Add("by", Format(BrewYieldBonus));
			Add("bb", Format(BrewBloodDrainReduction));
			Add("bs", Format(BrewSunResistance));
			Add("bh", Format(BrewHolyResistance));
			Add("bg", Format(BrewGarlicResistance));
			Add("bp", Format(BrewPowerBonus));
			Add("sy", Format(SealYieldBonus));
			Add("sb", Format(SealBloodDrainReduction));
			Add("sr", Format(SealResistance));
			Add("sp", Format(SealPowerBonus));
			Add("ss", Format(SealSetMultiplier));
			Add("rq", Format(RodQualityPoints));
			Add("ar", Format(ReelBiteDelayFactor));
			Add("ah", Format(ReelHaulFactor));
			Add("af", Format(FloatReactionFactor));
			Add("am", Format(MagnetJunkFactor));
			return string.Join(' '.ToString(), words);
			void Add(string name, string value)
			{
				words.Add(name + "=" + value);
			}
		}

		public static GearBalance FromWire(string words)
		{
			GearBalance gearBalance = new GearBalance();
			if (string.IsNullOrEmpty(words))
			{
				return gearBalance;
			}
			string[] array = words.Split(' ');
			foreach (string text in array)
			{
				int num = text.IndexOf('=');
				string value;
				if (num > 0)
				{
					string text2 = text.Substring(0, num);
					value = text.Substring(num + 1);
					switch (text2)
					{
					case "bd":
						Tiers(ref gearBalance.BrewDurationMinutes, 3);
						break;
					case "be":
						Tiers(ref gearBalance.BrewEssenceAmount, 3);
						break;
					case "by":
						Tiers(ref gearBalance.BrewYieldBonus, 3);
						break;
					case "bb":
						Tiers(ref gearBalance.BrewBloodDrainReduction, 3);
						break;
					case "bs":
						Tiers(ref gearBalance.BrewSunResistance, 3);
						break;
					case "bh":
						Tiers(ref gearBalance.BrewHolyResistance, 3);
						break;
					case "bg":
						Tiers(ref gearBalance.BrewGarlicResistance, 3);
						break;
					case "bp":
						Tiers(ref gearBalance.BrewPowerBonus, 3);
						break;
					case "sy":
						One(ref gearBalance.SealYieldBonus);
						break;
					case "sb":
						One(ref gearBalance.SealBloodDrainReduction);
						break;
					case "sr":
						One(ref gearBalance.SealResistance);
						break;
					case "sp":
						One(ref gearBalance.SealPowerBonus);
						break;
					case "ss":
						One(ref gearBalance.SealSetMultiplier);
						break;
					case "rq":
						Tiers(ref gearBalance.RodQualityPoints, 3);
						break;
					case "ar":
						One(ref gearBalance.ReelBiteDelayFactor);
						break;
					case "ah":
						One(ref gearBalance.ReelHaulFactor);
						break;
					case "af":
						One(ref gearBalance.FloatReactionFactor);
						break;
					case "am":
						One(ref gearBalance.MagnetJunkFactor);
						break;
					}
				}
				void One(ref float target)
				{
					if (TryParse(value, 1, out var values))
					{
						target = values[0];
					}
				}
				void Tiers(ref float[] target, int count)
				{
					if (TryParse(value, count, out var values))
					{
						target = values;
					}
				}
			}
			return gearBalance;
		}
	}
	public sealed class HaulGameRules
	{
		public uint Seed;

		public float Seconds;

		public float SlackSeconds;

		public float Zone;

		public float FishSpeed;

		public float TimeLimit;
	}
	public enum HaulOutcome
	{
		Running,
		Landed,
		GotAway,
		OutOfTime
	}
	public sealed class HaulGame
	{
		public const int TicksPerSecond = 20;

		public const float TickSeconds = 0.05f;

		public const int MaxPull = 255;

		public const float StartProgress = 0.3f;

		private const float Middle = 0.5f;

		private const float Half = 0.5f;

		private const float Full = 1f;

		private const float StartPauseSeconds = 1f;

		private const float LiftPerSecond = 2.8f;

		private const float FallPerSecond = 2.2f;

		private const float SpeedKeptPerTick = 0.9f;

		private const float MinPauseSeconds = 0.2f;

		private const float MaxPauseSeconds = 0.9f;

		private const float MinHop = 0.15f;

		private const float DartChance = 0.3f;

		private const float DartSpeedFactor = 1.8f;

		private const int ShiftA = 13;

		private const int ShiftB = 17;

		private const int ShiftC = 5;

		private const uint SeedForZero = 2654435769u;

		private const int RandomBits = 24;

		private const float RandomUnit = 5.9604645E-08f;

		private const int BitsOfState = 32;

		private readonly HaulGameRules _rules;

		private readonly int _limitTicks;

		private uint _random;

		private float _markerSpeed;

		private float _fishTarget;

		private float _fishSpeed;

		private int _pauseTicks;

		public HaulGameRules Rules => _rules;

		public HaulOutcome Outcome { get; private set; }

		public int Tick { get; private set; }

		public float Marker { get; private set; }

		public float Fish { get; private set; }

		public float Progress { get; private set; }

		public float PreviousMarker { get; private set; }

		public float PreviousFish { get; private set; }

		public float PreviousProgress { get; private set; }

		public bool MarkerOnFish => Math.Abs(Marker - Fish) <= _rules.Zone * 0.5f;

		public float SecondsLeft => (float)Math.Max(0, _limitTicks - Tick) * 0.05f;

		public HaulGame(HaulGameRules rules)
		{
			_rules = rules;
			_limitTicks = (int)(rules.TimeLimit * 20f);
			_random = ((rules.Seed == 0) ? 2654435769u : rules.Seed);
			Marker = (PreviousMarker = 0.5f);
			Fish = (PreviousFish = (_fishTarget = 0.5f));
			Progress = (PreviousProgress = 0.3f);
			_pauseTicks = 20;
		}

		public void Step(bool held)
		{
			Step(held ? 255 : 0);
		}

		public static int PullOf(float press)
		{
			return (int)Math.Round(Math.Min(Math.Max(press, 0f), 1f) * 255f);
		}

		public void Step(int pull)
		{
			if (Outcome == HaulOutcome.Running)
			{
				pull = Math.Min(Math.Max(pull, 0), 255);
				PreviousMarker = Marker;
				PreviousFish = Fish;
				PreviousProgress = Progress;
				float num = -2.2f + 5f * (float)pull / 255f;
				_markerSpeed = (_markerSpeed + num * 0.05f) * 0.9f;
				Marker += _markerSpeed * 0.05f;
				if (Marker <= 0f || Marker >= 1f)
				{
					Marker = ((Marker <= 0f) ? 0f : 1f);
					_markerSpeed = 0f;
				}
				MoveFish();
				Progress += (MarkerOnFish ? (0.05f / _rules.Seconds) : (-0.05f / _rules.SlackSeconds));
				Tick++;
				if (Progress >= 1f)
				{
					Progress = 1f;
					Outcome = HaulOutcome.Landed;
				}
				else if (Progress <= 0f)
				{
					Progress = 0f;
					Outcome = HaulOutcome.GotAway;
				}
				else if (Tick >= _limitTicks)
				{
					Outcome = HaulOutcome.OutOfTime;
				}
			}
		}

		private void MoveFish()
		{
			if (_pauseTicks > 0)
			{
				_pauseTicks--;
				if (_pauseTicks == 0)
				{
					PickFishTarget();
				}
				return;
			}
			float num = _fishSpeed * 0.05f;
			float num2 = _fishTarget - Fish;
			if (Math.Abs(num2) > num)
			{
				Fish += ((num2 > 0f) ? num : (0f - num));
				return;
			}
			Fish = _fishTarget;
			float num3 = 0.2f + 0.7f * NextRandom();
			_pauseTicks = Math.Max(1, (int)(num3 * 20f));
		}

		private void PickFishTarget()
		{
			float num = _rules.Zone * 0.5f;
			float num2 = 1f - _rules.Zone;
			float num3 = num + num2 * NextRandom();
			if (Math.Abs(num3 - Fish) < 0.15f)
			{
				num3 = ((Fish < 0.5f) ? Math.Min(num + num2, Fish + 0.15f) : Math.Max(num, Fish - 0.15f));
			}
			_fishTarget = num3;
			_fishSpeed = _rules.FishSpeed * ((NextRandom() < 0.3f) ? 1.8f : 1f);
		}

		private float NextRandom()
		{
			_random ^= _random << 13;
			_random ^= _random >> 17;
			_random ^= _random << 5;
			return (float)(_random >> 8) * 5.9604645E-08f;
		}

		public static HaulOutcome Replay(HaulGameRules rules, IReadOnlyList<int> pulls, out int ticks)
		{
			HaulGame haulGame = new HaulGame(rules);
			for (int i = 0; i < pulls.Count; i++)
			{
				if (haulGame.Outcome != HaulOutcome.Running)
				{
					break;
				}
				haulGame.Step(pulls[i]);
			}
			ticks = haulGame.Tick;
			return haulGame.Outcome;
		}
	}
	public static class HaulInput
	{
		public const string None = "-";

		public const int StepsPerPart = 160;

		private const int DigitsPerStep = 2;

		private const int DigitBase = 16;

		private const string Digits = "0123456789abcdef";

		public static string ToText(IReadOnlyList<int> pulls, int from, int count)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = from; i < from + count && i < pulls.Count; i++)
			{
				int num = Math.Min(Math.Max(pulls[i], 0), 255);
				stringBuilder.Append("0123456789abcdef"[num / 16]).Append("0123456789abcdef"[num % 16]);
			}
			if (stringBuilder.Length != 0)
			{
				return stringBuilder.ToString();
			}
			return "-";
		}

		public static string ToText(IReadOnlyList<int> pulls)
		{
			return ToText(pulls, 0, pulls.Count);
		}

		public static bool TryParse(string text, int maxSteps, out int[] pulls)
		{
			pulls = Array.Empty<int>();
			if (text == null)
			{
				return false;
			}
			text = text.Trim();
			if (text == "-")
			{
				return true;
			}
			if (text.Length == 0 || text.Length % 2 != 0 || text.Length / 2 > maxSteps)
			{
				return false;
			}
			int[] array = new int[text.Length / 2];
			for (int i = 0; i < array.Length; i++)
			{
				int num = "0123456789abcdef".IndexOf(char.ToLowerInvariant(text[i * 2]));
				int num2 = "0123456789abcdef".IndexOf(char.ToLowerInvariant(text[i * 2 + 1]));
				if (num < 0 || num2 < 0)
				{
					return false;
				}
				array[i] = num * 16 + num2;
			}
			pulls = array;
			return true;
		}
	}
	public static class JsonFiles
	{
		private static readonly JsonSerializerOptions Options = new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			AllowTrailingCommas = true,
			Converters = { (JsonConverter)new JsonStringEnumConverter() }
		};

		public static T Parse<T>(string json) where T : class
		{
			return JsonSerializer.Deserialize<T>(json, Options);
		}
	}
	public enum FishRarity
	{
		Common,
		Uncommon,
		Rare,
		Legendary
	}
	public sealed class LootEntry
	{
		public string Id { get; set; }

		public string DisplayName { get; set; }

		public string DisplayNamePl { get; set; }

		public FishRarity Rarity { get; set; }

		public string Item { get; set; }

		public float Weight { get; set; } = 1f;

		public int Quantity { get; set; } = 1;

		public CatchTime Time { get; set; }

		public int MinRodTier { get; set; } = 1;

		public WaterNeed Water { get; set; }

		public string Bait { get; set; }

		public float Chance { get; set; } = 0.25f;

		public int MinQuality { get; set; }

		public bool FullStreak { get; set; }

		public bool BloodMoon { get; set; }

		public List<SpotEffect> SpotEffects { get; set; } = new List<SpotEffect>();

		public List<string> SpotAppearEffects { get; set; } = new List<string>();

		public LegendFight Fight { get; set; }

		public SpotRadiation Radiation { get; set; }

		public FishHaul Haul { get; set; }

		public bool IsAvailable(CatchContext context)
		{
			if (context.RodTier < MinRodTier)
			{
				return false;
			}
			if (!WaterRules.Satisfies(context.Water, Water))
			{
				return false;
			}
			if (Time == CatchTime.Night)
			{
				return context.IsNight;
			}
			if (Time == CatchTime.Day)
			{
				return !context.IsNight;
			}
			return true;
		}

		public bool IsLegendaryAttempt(CatchContext context, int quality)
		{
			if (Rarity != FishRarity.Legendary || !context.IsLegendarySpot || !IsAvailable(context))
			{
				return false;
			}
			if (quality < MinQuality)
			{
				return false;
			}
			if (FullStreak && !context.HasFullStreak)
			{
				return false;
			}
			if (BloodMoon && !context.IsBloodMoon)
			{
				return false;
			}
			if (context.Bait != null)
			{
				return string.Equals(context.Bait.Item, Bait, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}
	}
	public sealed class SpotEffect
	{
		public string Prefab { get; set; }

		public float Seconds { get; set; } = 4f;

		public int Instances { get; set; } = 1;
	}
	public sealed class FightMonster
	{
		public string Prefab { get; set; }

		public int Count { get; set; } = 1;
	}
	public sealed class LegendFight
	{
		public List<FightWave> Waves { get; set; } = new List<FightWave>();
	}
	public sealed class FightWave
	{
		public float Seconds { get; set; } = 60f;

		public List<FightMonster> Monsters { get; set; } = new List<FightMonster>();

		public List<FightMonster> Hazards { get; set; } = new List<FightMonster>();

		public List<string> Effects { get; set; } = new List<string>();
	}
	public sealed class SpotRadiation
	{
		public string Prefab { get; set; }

		public float Radius { get; set; } = 20f;
	}
	public sealed class FishHaul
	{
		public float Seconds { get; set; } = 10f;

		public float SlackSeconds { get; set; } = 10f;

		public float Zone { get; set; } = 0.26f;

		public float FishSpeed { get; set; } = 0.35f;

		public float TimeLimit { get; set; } = 45f;

		public float SunFactor { get; set; } = 0.5f;

		public int MinHealthPercent { get; set; } = 25;

		public float Reach { get; set; } = 15f;
	}
	public enum HaulState
	{
		Holding,
		TooWeak,
		TooFar
	}
	public static class HaulRules
	{
		private const float Percent = 100f;

		public static float SecondsFor(FishHaul haul, bool inSun)
		{
			if (!inSun)
			{
				return haul.Seconds;
			}
			return haul.Seconds * haul.SunFactor;
		}

		public static HaulGameRules GameFor(FishHaul haul, bool inSun, uint seed, float gearFactor = 1f)
		{
			return new HaulGameRules
			{
				Seed = seed,
				Seconds = SecondsFor(haul, inSun) * gearFactor,
				SlackSeconds = haul.SlackSeconds,
				Zone = haul.Zone,
				FishSpeed = haul.FishSpeed,
				TimeLimit = haul.TimeLimit
			};
		}

		public static HaulState StateOf(FishHaul haul, float healthShare, float distance)
		{
			if (healthShare * 100f < (float)haul.MinHealthPercent)
			{
				return HaulState.TooWeak;
			}
			if (!(distance > haul.Reach))
			{
				return HaulState.Holding;
			}
			return HaulState.TooFar;
		}
	}
	public static class LegendaryRules
	{
		public const float DefaultChance = 0.25f;

		public const int FishCount = 1;

		public const float DefaultSecondsPerWave = 60f;

		public const float DefaultSpotEffectSeconds = 4f;

		public const float DefaultRadiationRadius = 20f;

		public const float DefaultHaulSeconds = 10f;

		public const float DefaultHaulSlackSeconds = 10f;

		public const float DefaultHaulZone = 0.26f;

		public const float DefaultHaulFishSpeed = 0.35f;

		public const float DefaultHaulTimeLimit = 45f;

		public const float MaxHaulTimeLimit = 120f;

		public const float DefaultHaulSunFactor = 0.5f;

		public const int DefaultHaulMinHealthPercent = 25;

		public const float DefaultHaulReach = 15f;

		public const int MaxHaulMinHealthPercent = 99;
	}
	public enum CatchTime
	{
		Any,
		Day,
		Night
	}
	public struct CatchContext
	{
		public bool IsNight;

		public bool IsBloodMoon;

		public bool HasFullStreak;

		public bool IsLegendarySpot;

		public BaitDefinition Bait;

		public int RodTier;

		public float RarityShift;

		public WaterType Water;

		public static CatchContext Unrestricted(bool isNight)
		{
			return new CatchContext
			{
				IsNight = isNight,
				RodTier = int.MaxValue,
				Water = WaterType.Silver
			};
		}
	}
	public sealed class BiomeTable
	{
		public string Biome { get; set; }

		public string DisplayName { get; set; }

		public string DisplayNamePl { get; set; }

		public List<string> Aliases { get; set; } = new List<string>();

		public Dictionary<FishRarity, float> RarityChances { get; set; } = new Dictionary<FishRarity, float>();

		public List<LootEntry> Fish { get; set; } = new List<LootEntry>();

		public List<LootEntry> Junk { get; set; } = new List<LootEntry>();

		public List<DeepMonsterGroup> DeepMonsters { get; set; } = new List<DeepMonsterGroup>();
	}
	public sealed class LootTableFile
	{
		public const int CurrentSchemaVersion = 1;

		public int SchemaVersion { get; set; }

		public List<BiomeTable> Biomes { get; set; } = new List<BiomeTable>();

		public Dictionary<FishRarity, FishHaul> Hauls { get; set; } = new Dictionary<FishRarity, FishHaul>();

		public FishHaul HaulOf(LootEntry fish)
		{
			if (fish.Haul != null)
			{
				return fish.Haul;
			}
			if (Hauls == null || !Hauls.TryGetValue(fish.Rarity, out var value))
			{
				return null;
			}
			return value;
		}

		public BiomeTable FindBiome(string biome)
		{
			foreach (BiomeTable biome2 in Biomes)
			{
				if (string.Equals(biome2.Biome, biome, StringComparison.OrdinalIgnoreCase))
				{
					return biome2;
				}
				foreach (string item in biome2.Aliases ?? new List<string>())
				{
					if (string.Equals(item, biome, StringComparison.OrdinalIgnoreCase))
					{
						return biome2;
					}
				}
			}
			return null;
		}

		public LootEntry FindFish(string id)
		{
			foreach (BiomeTable biome in Biomes)
			{
				foreach (LootEntry item in biome.Fish)
				{
					if (string.Equals(item.Id, id, StringComparison.OrdinalIgnoreCase))
					{
						return item;
					}
				}
			}
			return null;
		}
	}
	public static class LootTableLoader
	{
		public static LootTableFile Parse(string json)
		{
			return JsonFiles.Parse<LootTableFile>(json) ?? new LootTableFile();
		}
	}
	public static class LootTableValidator
	{
		private const float ChanceSumTolerance = 0.001f;

		private const float FullChance = 1f;

		private static void ValidateHaul(string label, FishHaul haul, List<string> errors)
		{
			if (haul.Seconds <= 0f)
			{
				errors.Add(label + ": seconds of the haul must be above 0");
			}
			if (haul.SlackSeconds <= 0f)
			{
				errors.Add(label + ": slackSeconds of the haul must be above 0");
			}
			if (haul.Zone <= 0f || haul.Zone >= 1f)
			{
				errors.Add(label + ": zone of the haul must be above 0 and under 1");
			}
			if (haul.FishSpeed < 0f)
			{
				errors.Add(label + ": fishSpeed of the haul must be 0 or more");
			}
			if (haul.TimeLimit <= 0f || haul.TimeLimit > 120f)
			{
				errors.Add($"{label}: timeLimit of the haul must be above 0 and at most {120f:0}");
			}
			if (haul.SunFactor <= 0f || haul.SunFactor > 1f)
			{
				errors.Add(label + ": sunFactor of the haul must be above 0 and at most 1");
			}
			if (haul.MinHealthPercent < 0 || haul.MinHealthPercent > 99)
			{
				errors.Add($"{label}: minHealthPercent of the haul must be between 0 and {99}");
			}
			if (haul.Reach <= 0f)
			{
				errors.Add(label + ": reach of the haul must be above 0");
			}
		}

		public static List<string> Validate(LootTableFile file, Func<string, bool> itemExists = null)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<FishRarity, FishHaul> item in file.Hauls ?? new Dictionary<FishRarity, FishHaul>())
			{
				if (item.Value == null)
				{
					list.Add($"hauls/{item.Key}: no haul");
				}
				else
				{
					ValidateHaul($"hauls/{item.Key}", item.Value, list);
				}
			}
			if (file.SchemaVersion != 1)
			{
				list.Add($"schemaVersion is {file.SchemaVersion}, expected {1}");
			}
			if (file.Biomes == null || file.Biomes.Count == 0)
			{
				list.Add("no biomes defined");
				return list;
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (BiomeTable biome in file.Biomes)
			{
				string text = "biome '" + biome.Biome + "'";
				if (string.IsNullOrWhiteSpace(biome.Biome))
				{
					list.Add("a biome has no name");
				}
				else if (!hashSet.Add(biome.Biome))
				{
					list.Add(text + ": defined more than once");
				}
				foreach (string item2 in biome.Aliases ?? new List<string>())
				{
					if (!hashSet.Add(item2))
					{
						list.Add(text + ": alias '" + item2 + "' is already used by a biome");
					}
				}
				HashSet<string> uniqueIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				float num = 0f;
				foreach (KeyValuePair<FishRarity, float> rarityChance in biome.RarityChances)
				{
					if (rarityChance.Key == FishRarity.Legendary)
					{
						list.Add(text + ": Legendary cannot have a rarity chance, it is gated by conditions");
					}
					if (rarityChance.Value < 0f)
					{
						list.Add($"{text}: negative chance for {rarityChance.Key}");
					}
					num += rarityChance.Value;
					if (rarityChance.Value > 0f && CatchRoller.TotalWeight(biome.Fish, rarityChance.Key) <= 0f)
					{
						list.Add($"{text}: {rarityChance.Key} has a chance but no fish with weight");
					}
				}
				if (Math.Abs(num - 1f) > 0.001f)
				{
					list.Add($"{text}: rarity chances sum to {num}, expected {1f}");
				}
				if (biome.Junk == null || CatchRoller.TotalWeight(biome.Junk) <= 0f)
				{
					list.Add(text + ": junk pool is empty");
				}
				ValidateEntries(biome.Fish, text + " fish", uniqueIds, itemExists, list);
				ValidateEntries(biome.Junk, text + " junk", null, itemExists, list);
				ValidateMonsters(biome.DeepMonsters, text, itemExists, list);
			}
			return list;
		}

		private static void ValidateMonsters(List<DeepMonsterGroup> groups, string where, Func<string, bool> prefabExists, List<string> errors)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (DeepMonsterGroup item in groups ?? new List<DeepMonsterGroup>())
			{
				string text = where + " deep monsters '" + item.Id + "'";
				if (string.IsNullOrWhiteSpace(item.Id))
				{
					errors.Add(where + ": a group of deep monsters has no id");
				}
				else if (!hashSet.Add(item.Id))
				{
					errors.Add(text + ": duplicate id");
				}
				if (item.Weight < 0f)
				{
					errors.Add(text + ": negative weight");
				}
				if (item.Seconds <= 0f)
				{
					errors.Add(text + ": seconds must be above 0");
				}
				if (item.Monsters == null || item.Monsters.Count == 0)
				{
					errors.Add(text + ": needs monsters");
				}
				foreach (FightMonster item2 in item.Monsters ?? new List<FightMonster>())
				{
					if (item2.Count < 1)
					{
						errors.Add(text + ": count of '" + item2.Prefab + "' must be at least 1");
					}
					if (string.IsNullOrWhiteSpace(item2.Prefab) || (prefabExists != null && !prefabExists(item2.Prefab)))
					{
						errors.Add(text + ": unknown monster prefab '" + item2.Prefab + "'");
					}
				}
				foreach (MonsterLoot item3 in item.Loot ?? new List<MonsterLoot>())
				{
					if (string.IsNullOrWhiteSpace(item3.Item) || (prefabExists != null && !prefabExists(item3.Item)))
					{
						errors.Add(text + ": unknown loot item prefab '" + item3.Item + "'");
					}
					if (item3.Min < 1 || item3.Max < item3.Min)
					{
						errors.Add(text + ": loot '" + item3.Item + "' needs 1 <= min <= max");
					}
					if (item3.Chance <= 0f || item3.Chance > 1f)
					{
						errors.Add(text + ": chance of loot '" + item3.Item + "' must be above 0 and at most 1");
					}
				}
			}
		}

		private static List<string> AllSpotEffects(LootEntry entry)
		{
			List<string> list = new List<string>();
			foreach (SpotEffect item in entry.SpotEffects ?? new List<SpotEffect>())
			{
				list.Add(item.Prefab);
			}
			list.AddRange(entry.SpotAppearEffects ?? new List<string>());
			return list;
		}

		private static void ValidateEntries(List<LootEntry> entries, string where, HashSet<string> uniqueIds, Func<string, bool> itemExists, List<string> errors)
		{
			if (entries == null)
			{
				return;
			}
			foreach (LootEntry entry in entries)
			{
				string text = where + " '" + entry.Id + "'";
				if (string.IsNullOrWhiteSpace(entry.Id))
				{
					errors.Add(where + ": entry without id");
				}
				else if (uniqueIds != null && !uniqueIds.Add(entry.Id))
				{
					errors.Add(text + ": duplicate id");
				}
				if (entry.Weight < 0f)
				{
					errors.Add(text + ": negative weight");
				}
				if (entry.Quantity < 1)
				{
					errors.Add(text + ": quantity must be at least 1");
				}
				if (entry.MinRodTier < 1)
				{
					errors.Add($"{text}: minRodTier must be at least {1}");
				}
				if (entry.Rarity == FishRarity.Legendary)
				{
					if (string.IsNullOrWhiteSpace(entry.Bait))
					{
						errors.Add(text + ": a Legendary fish needs a bait item");
					}
					else if (itemExists != null && !itemExists(entry.Bait))
					{
						errors.Add(text + ": unknown bait item prefab '" + entry.Bait + "'");
					}
					foreach (SpotEffect item in entry.SpotEffects ?? new List<SpotEffect>())
					{
						if (item.Seconds <= 0f)
						{
							errors.Add(text + ": seconds of spot effect '" + item.Prefab + "' must be above 0");
						}
						if (item.Instances < 1)
						{
							errors.Add(text + ": instances of spot effect '" + item.Prefab + "' must be at least 1");
						}
					}
					foreach (string item2 in AllSpotEffects(entry))
					{
						if (itemExists != null && !itemExists(item2))
						{
							errors.Add(text + ": unknown spot effect prefab '" + item2 + "'");
						}
					}
					if (entry.Fight != null)
					{
						if (entry.Fight.Waves == null || entry.Fight.Waves.Count == 0)
						{
							errors.Add(text + ": a fight needs at least one wave");
						}
						int num = 0;
						foreach (FightWave item3 in entry.Fight.Waves ?? new List<FightWave>())
						{
							string text2 = $"{text} wave {++num}";
							if (item3.Seconds <= 0f)
							{
								errors.Add(text2 + ": seconds must be above 0");
							}
							if (item3.Monsters == null || item3.Monsters.Count == 0)
							{
								errors.Add(text2 + ": needs monsters");
							}
							List<FightMonster> list = new List<FightMonster>(item3.Monsters ?? new List<FightMonster>());
							list.AddRange(item3.Hazards ?? new List<FightMonster>());
							foreach (FightMonster item4 in list)
							{
								if (item4.Count < 1)
								{
									errors.Add(text2 + ": count of '" + item4.Prefab + "' must be at least 1");
								}
								if (string.IsNullOrWhiteSpace(item4.Prefab) || (itemExists != null && !itemExists(item4.Prefab)))
								{
									errors.Add(text2 + ": unknown monster prefab '" + item4.Prefab + "'");
								}
							}
							foreach (string item5 in item3.Effects ?? new List<string>())
							{
								if (itemExists != null && !itemExists(item5))
								{
									errors.Add(text2 + ": unknown effect prefab '" + item5 + "'");
								}
							}
						}
					}
					if (entry.Radiation != null)
					{
						if (entry.Radiation.Radius <= 0f)
						{
							errors.Add(text + ": radius of the radiation must be above 0");
						}
						if (string.IsNullOrWhiteSpace(entry.Radiation.Prefab) || (itemExists != null && !itemExists(entry.Radiation.Prefab)))
						{
							errors.Add(text + ": unknown radiation zone prefab '" + entry.Radiation.Prefab + "'");
						}
					}
					if (entry.Haul != null && entry.Fight != null)
					{
						errors.Add(text + ": a fish has a fight or a haul, not both");
					}
					if (entry.Chance <= 0f || entry.Chance > 1f)
					{
						errors.Add(text + ": chance must be above 0 and at most 1");
					}
				}
				else if (!string.IsNullOrWhiteSpace(entry.Bait) || entry.FullStreak || entry.BloodMoon || entry.MinQuality > 0 || AllSpotEffects(entry).Count > 0 || entry.Fight != null || entry.Radiation != null)
				{
					errors.Add(text + ": bait, fullStreak, bloodMoon, minQuality, spot effects, fight and radiation apply to Legendary fish only");
				}
				if (entry.Haul != null)
				{
					ValidateHaul(text, entry.Haul, errors);
				}
				if (string.IsNullOrWhiteSpace(entry.Item))
				{
					errors.Add(text + ": no item");
				}
				else if (itemExists != null && !itemExists(entry.Item))
				{
					errors.Add(text + ": unknown item prefab '" + entry.Item + "'");
				}
			}
		}
	}
	public enum DropKind
	{
		Item,
		Group,
		Unit
	}
	public struct DropEntry
	{
		public string Prefab;

		public int Quantity;

		public int Weight;

		public DropKind Kind;
	}
	public static class MissionLoot
	{
		public const int WeightScale = 100;

		private const int LeastWeight = 1;

		public static List<DropEntry> Without(IReadOnlyList<DropEntry> mission, Func<string, IReadOnlyList<DropEntry>> groupOf, Func<string, bool> allowed)
		{
			List<DropEntry> list = new List<DropEntry>();
			bool flag = false;
			foreach (DropEntry item in mission)
			{
				if (item.Kind != DropKind.Group)
				{
					if (item.Kind == DropKind.Item && !allowed(item.Prefab))
					{
						flag = true;
					}
					else
					{
						Add(list, item.Prefab, item.Quantity, item.Weight * 100, item.Kind);
					}
					continue;
				}
				List<(DropEntry, double)> list2 = new List<(DropEntry, double)>();
				bool taken = false;
				if (!TryLayOpen(item.Prefab, 1.0, groupOf, allowed, list2, ref taken, new HashSet<string>(StringComparer.OrdinalIgnoreCase)) || !taken)
				{
					Add(list, item.Prefab, item.Quantity, item.Weight * 100, DropKind.Group);
					continue;
				}
				flag = true;
				double num = 0.0;
				foreach (var item2 in list2)
				{
					num += item2.Item2;
				}
				if (num <= 0.0)
				{
					continue;
				}
				foreach (var item3 in list2)
				{
					Add(list, item3.Item1.Prefab, item3.Item1.Quantity, Math.Max(1, (int)Math.Round((double)(item.Weight * 100) * item3.Item2 / num)), item3.Item1.Kind);
				}
			}
			if (!flag)
			{
				return null;
			}
			return list;
		}

		private static bool TryLayOpen(string group, double share, Func<string, IReadOnlyList<DropEntry>> groupOf, Func<string, bool> allowed, List<(DropEntry Entry, double Share)> into, ref bool taken, HashSet<string> open)
		{
			IReadOnlyList<DropEntry> readOnlyList = groupOf(group);
			if (readOnlyList == null || !open.Add(group))
			{
				return false;
			}
			long num = 0L;
			foreach (DropEntry item in readOnlyList)
			{
				num += Math.Max(0, item.Weight);
			}
			if (num <= 0)
			{
				return false;
			}
			foreach (DropEntry item2 in readOnlyList)
			{
				double num2 = share * (double)Math.Max(0, item2.Weight) / (double)num;
				if (item2.Kind == DropKind.Group)
				{
					if (!TryLayOpen(item2.Prefab, num2, groupOf, allowed, into, ref taken, open))
					{
						return false;
					}
				}
				else if (item2.Kind == DropKind.Item && !allowed(item2.Prefab))
				{
					taken = true;
				}
				else
				{
					into.Add((item2, num2));
				}
			}
			open.Remove(group);
			return true;
		}

		private static void Add(List<DropEntry> group, string prefab, int quantity, int weight, DropKind kind)
		{
			for (int i = 0; i < group.Count; i++)
			{
				DropEntry value = group[i];
				if (value.Kind == kind && value.Quantity == quantity && string.Equals(value.Prefab, prefab, StringComparison.OrdinalIgnoreCase))
				{
					value.Weight += weight;
					group[i] = value;
					return;
				}
			}
			group.Add(new DropEntry
			{
				Prefab = prefab,
				Quantity = quantity,
				Weight = weight,
				Kind = kind
			});
		}
	}
	public static class ModInfo
	{
		public const string Name = "DeepRising";

		public const string ServerGuid = "kpajak.deeprising.server";

		public const string ClientGuid = "kpajak.deeprising.client";

		public const string Version = "0.1.0";

		public const string ServerProductName = "VRisingServer";

		public const string ConfigFileName = "DeepRising.cfg";

		public const string DataDirectoryName = "DeepRising";

		public const string LootTablesFileName = "loot_tables.json";

		public const string RodUpgradesFileName = "rod_upgrades.json";

		public const string BaitsFileName = "baits.json";
	}
	public static class Polygons
	{
		public const int MinVertices = 3;

		public static bool Contains(float[] xs, float[] zs, float x, float z)
		{
			if (xs == null || zs == null || xs.Length != zs.Length || xs.Length < 3)
			{
				return false;
			}
			bool flag = false;
			int num = 0;
			int num2 = xs.Length - 1;
			while (num < xs.Length)
			{
				if (zs[num] > z != zs[num2] > z && x < (xs[num2] - xs[num]) * (z - zs[num]) / (zs[num2] - zs[num]) + xs[num])
				{
					flag = !flag;
				}
				num2 = num++;
			}
			return flag;
		}
	}
	public static class ProgressionDefaults
	{
		public const int AnglerMaxLevel = 100;

		public const float AnglerXpMultiplier = 1f;

		public const int XpPerLevelBase = 50;

		public const int XpPerLevelGrowth = 10;
	}
	public static class ProgressionRules
	{
		public const int FirstLevel = 1;

		public const int CommonFishXp = 10;

		public const int UncommonFishXp = 25;

		public const int RareFishXp = 60;

		public const int LegendaryFishXp = 250;

		public const int LevelsPerQualityPoint = 10;

		public const int MaxLevelQualityPoints = 10;

		public const int LongerReactionLevel = 20;

		public const float LongerReactionFactor = 1.1f;

		public const int EasierPerfectLevel = 60;

		public const int WaterSenseLevel = 10;

		public const int LegendaryNewsLevel = 100;

		public const int EasierPerfectThreshold = 85;
	}
	public sealed class ProgressionBalance
	{
		public int MaxLevel = 100;

		public float XpMultiplier = 1f;

		public int XpPerLevelBase = 50;

		public int XpPerLevelGrowth = 10;

		public int LevelsPerQualityPoint = 10;

		public int MaxLevelQualityPoints = 10;

		public int LongerReactionLevel = 20;

		public float LongerReactionFactor = 1.1f;

		public int EasierPerfectLevel = 60;

		public int LegendaryNewsLevel = 100;

		public int WaterSenseLevel = 10;

		public int EasierPerfectThreshold = 85;
	}
	public static class Progression
	{
		public static ProgressionBalance Levels = new ProgressionBalance();

		public static int BaseXpOf(FishRarity rarity)
		{
			return rarity switch
			{
				FishRarity.Uncommon => 25, 
				FishRarity.Rare => 60, 
				FishRarity.Legendary => 250, 
				_ => 10, 
			};
		}

		public static int XpForCatch(CatchResult result, ProgressionBalance balance)
		{
			if (result.Outcome != CatchOutcome.Fish)
			{
				return 0;
			}
			return Math.Max((int)Math.Round((float)BaseXpOf(result.Entry.Rarity) * QualityCalculator.XpMultiplierOf(result.Grade) * balance.XpMultiplier), 0);
		}

		public static long TotalXpForLevel(int level, ProgressionBalance balance)
		{
			long num = Math.Clamp(level, 1, balance.MaxLevel) - 1;
			return num * balance.XpPerLevelBase + balance.XpPerLevelGrowth * num * (num + 1) / 2;
		}

		public static int LevelForXp(long totalXp, ProgressionBalance balance)
		{
			int i;
			for (i = 1; i < balance.MaxLevel && totalXp >= TotalXpForLevel(i + 1, balance); i++)
			{
			}
			return i;
		}

		public static long XpToNextLevel(long totalXp, ProgressionBalance balance)
		{
			int num = LevelForXp(totalXp, balance);
			if (num < balance.MaxLevel)
			{
				return TotalXpForLevel(num + 1, balance) - totalXp;
			}
			return 0L;
		}

		public static bool SensesWater(int level)
		{
			return level >= Levels.WaterSenseLevel;
		}

		public static bool HearsOfLegendarySpots(int level)
		{
			return level >= Levels.LegendaryNewsLevel;
		}

		public static int QualityPointsOf(int level)
		{
			return Math.Clamp(level / Math.Max(1, Levels.LevelsPerQualityPoint), 0, Math.Max(0, Levels.MaxLevelQualityPoints));
		}

		public static FishingBalance ApplyLevel(FishingBalance balance, int level)
		{
			FishingBalance fishingBalance = balance.Clone();
			if (level >= Levels.LongerReactionLevel)
			{
				fishingBalance.MaxReactionSeconds *= Levels.LongerReactionFactor;
			}
			if (level >= Levels.EasierPerfectLevel)
			{
				fishingBalance.PerfectCatchThreshold = Math.Min(fishingBalance.PerfectCatchThreshold, Levels.EasierPerfectThreshold);
			}
			return fishingBalance;
		}
	}
	public struct BaitListEntry
	{
		public string Id;

		public int Owned;

		public string Item;

		public string Label;

		public string Description;
	}
	public struct CodexRegionEntry
	{
		public string Biome;

		public string Name;

		public int Known;

		public int Total;

		public bool Complete;

		public int BonusPoints;
	}
	public struct CodexFishEntry
	{
		public string Id;

		public string Item;

		public string Name;

		public FishRarity Rarity;

		public int Catches;

		public int BestQuality;

		public string FirstCaught;

		public int TrophyQuality;

		public string Needs;

		public bool IsKnown => Catches > 0;
	}
	public enum PageRowStyle
	{
		Heading,
		Row,
		Bar,
		Level,
		Milestone,
		MilestoneReached
	}
	public struct PageRow
	{
		public string Page;

		public PageRowStyle Style;

		public string Icon;

		public string First;

		public string Second;

		public string Third;

		public string Button;

		public string Command;
	}
	public static class Protocol
	{
		public const string HelloPrefix = "[DeepRising:hello] ";

		public const string ProbeInventoryMarker = "[DeepRising:probe-inventory]";

		private const string HelloSuffix = " - this server runs DeepRising; the matching client module is required.";

		private const string SettingsEnd = "-";

		private const string BaitsCommand = ".fish baits ";

		public const string WholeList = "all";

		public const string English = "en";

		public const string Polish = "pl";

		public const string OnHookOnly = "hook";

		public const string BaitChoiceCommand = ".fish bait ";

		public const string RodCommand = ".fish rod";

		public const string NoBait = "off";

		private const string BaitOnHookPrefix = "[DeepRising:hook] ";

		private const string BaitLinePrefix = "[DeepRising:bait] ";

		public const string BaitListEnd = "[DeepRising:baits-end]";

		private const char FieldSeparator = '|';

		private const int BaitFields = 5;

		public const string GearChoiceCommand = ".fish gear ";

		private const string GearOnRodPrefix = "[DeepRising:gear-on] ";

		private const string GearLinePrefix = "[DeepRising:gear] ";

		private const string BannerPrefix = "[DeepRising:banner] ";

		private const string SearchAreaPrefix = "[DeepRising:area] ";

		public const string SchoolAreaPrefix = "school:";

		private const int AreaFields = 5;

		private const string WaterNearPrefix = "[DeepRising:water-near] ";

		private const int NoWater = -1;

		private const string WaterPlacesPrefix = "[DeepRising:water] ";

		private const string WaterOtherPlacesPrefix = "[DeepRising:water-not] ";

		private const string WaterFishPrefix = "[DeepRising:water-fish] ";

		public const string WaterOutlinesEnd = "[DeepRising:waters-end]";

		private const int WaterPlacesFields = 4;

		private const int WaterFishFields = 3;

		private const char CornerSeparator = ';';

		private const char CoordinateSeparator = ',';

		private const int CoordinatesPerCorner = 2;

		public const int WaterPlacesPerLine = 36;

		private const string CodexCommand = ".fish codexdata ";

		private const string CodexRegionPrefix = "[DeepRising:cx-region] ";

		private const string CodexFishPrefix = "[DeepRising:cx-fish] ";

		public const string CodexEnd = "[DeepRising:cx-end]";

		private const char RecordSeparator = ';';

		private const char RecordFieldSeparator = '~';

		private const int CodexRegionFields = 6;

		private const int CodexFishFields = 9;

		private const string True = "1";

		private const string False = "0";

		private const int MaxCodexRecordBytes = 380;

		private const string PageCommand = ".fish pagedata ";

		private const string PageRowPrefix = "[DeepRising:pg-row] ";

		public const string PageEnd = "[DeepRising:pg-end]";

		private const int PageRowFields = 8;

		public const string NamedIconPrefix = "icon:";

		private const string CellCommand = ".fish celldata ";

		private const string CellInfoPrefix = "[DeepRising:cell] ";

		private const int CellInfoFields = 2;

		private const string HaulStartPrefix = "[DeepRising:haul] ";

		public const string HaulCalledOff = "[DeepRising:haul-off]";

		private const string HaulAnswerCommand = ".fish haul ";

		private const int HaulFields = 10;

		private const string ExactNumber = "R";

		public const string HaulPartMore = "more";

		public const string HaulPartLast = "done";

		public static string BuildHello(string serverVersion)
		{
			return "[DeepRising:hello] " + serverVersion + " - this server runs DeepRising; the matching client module is required.";
		}

		public static string BuildHello(string serverVersion, string settings)
		{
			return "[DeepRising:hello] " + serverVersion + " " + settings + " - this server runs DeepRising; the matching client module is required.";
		}

		public static string BuildBaitListCommand(string language)
		{
			return ".fish baits all " + language;
		}

		public static string BuildBaitOnHookCommand(string language)
		{
			return ".fish baits hook " + language;
		}

		public static string BuildBaitOnHook(BaitListEntry? bait)
		{
			return "[DeepRising:hook] " + ((!bait.HasValue) ? "off" : Join(bait.Value));
		}

		public static bool TryParseBaitOnHook(string message, out BaitListEntry? bait)
		{
			bait = null;
			if (message == null || !message.StartsWith("[DeepRising:hook] ", StringComparison.Ordinal))
			{
				return false;
			}
			string text = message.Substring("[DeepRising:hook] ".Length).Trim();
			if (text == "off")
			{
				return true;
			}
			if (!TrySplit(text, out var entry))
			{
				return false;
			}
			bait = entry;
			return true;
		}

		public static string BuildBaitLine(BaitListEntry bait)
		{
			return "[DeepRising:bait] " + Join(bait);
		}

		public static bool TryParseBaitLine(string message, out BaitListEntry entry)
		{
			entry = default(BaitListEntry);
			if (message != null && message.StartsWith("[DeepRising:bait] ", StringComparison.Ordinal))
			{
				return TrySplit(message.Substring("[DeepRising:bait] ".Length), out entry);
			}
			return false;
		}

		public static string BuildGearOnRod(BaitListEntry? accessory)
		{
			return "[DeepRising:gear-on] " + ((!accessory.HasValue) ? "off" : Join(accessory.Value));
		}

		public static bool TryParseGearOnRod(string message, out BaitListEntry? accessory)
		{
			accessory = null;
			if (message == null || !message.StartsWith("[DeepRising:gear-on] ", StringComparison.Ordinal))
			{
				return false;
			}
			string text = message.Substring("[DeepRising:gear-on] ".Length).Trim();
			if (text == "off")
			{
				return true;
			}
			if (!TrySplit(text, out var entry))
			{
				return false;
			}
			accessory = entry;
			return true;
		}

		public static string BuildGearLine(BaitListEntry accessory)
		{
			return "[DeepRising:gear] " + Join(accessory);
		}

		public static bool TryParseGearLine(string message, out BaitListEntry entry)
		{
			entry = default(BaitListEntry);
			if (message != null && message.StartsWith("[DeepRising:gear] ", StringComparison.Ordinal))
			{
				return TrySplit(message.Substring("[DeepRising:gear] ".Length), out entry);
			}
			return false;
		}

		private static string Join(BaitListEntry bait)
		{
			return string.Join('|'.ToString(), bait.Id, bait.Owned.ToString(), bait.Item, Clean(bait.Label), Clean(bait.Description));
		}

		private static bool TrySplit(string text, out BaitListEntry entry)
		{
			entry = default(BaitListEntry);
			string[] array = text.Split('|');
			if (array.Length != 5 || !int.TryParse(array[1], out var result))
			{
				return false;
			}
			entry = new BaitListEntry
			{
				Id = array[0],
				Owned = result,
				Item = array[2],
				Label = array[3],
				Description = array[4]
			};
			return true;
		}

		public static string BuildBanner(string text)
		{
			return "[DeepRising:banner] " + text;
		}

		public static bool TryParseBanner(string message, out string text)
		{
			text = null;
			if (message == null || !message.StartsWith("[DeepRising:banner] ", StringComparison.Ordinal))
			{
				return false;
			}
			text = message.Substring("[DeepRising:banner] ".Length);
			return text.Length > 0;
		}

		public static string BuildSearchArea(string region, float x, float z, float radius, string legendItem)
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			return "[DeepRising:area] " + string.Join('|'.ToString(), region, x.ToString("F0", invariantCulture), z.ToString("F0", invariantCulture), radius.ToString("F0", invariantCulture), legendItem);
		}

		public static bool TryParseSearchArea(string message, out string region, out float x, out float z, out float radius, out string legendItem)
		{
			region = null;
			legendItem = null;
			x = (z = (radius = 0f));
			if (message == null || !message.StartsWith("[DeepRising:area] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:area] ".Length).Trim().Split('|');
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			NumberStyles style = NumberStyles.Float;
			if (array.Length != 5 || !float.TryParse(array[1], style, invariantCulture, out x) || !float.TryParse(array[2], style, invariantCulture, out z) || !float.TryParse(array[3], style, invariantCulture, out radius))
			{
				return false;
			}
			region = array[0];
			legendItem = array[4];
			return true;
		}

		public static string BuildWaterNear(WaterType? water)
		{
			return "[DeepRising:water-near] " + (int)(water.HasValue ? water.Value : ((WaterType)(-1)));
		}

		public static bool TryParseWaterNear(string message, out WaterType? water)
		{
			water = null;
			if (message == null || !message.StartsWith("[DeepRising:water-near] ", StringComparison.Ordinal))
			{
				return false;
			}
			if (!int.TryParse(message.Substring("[DeepRising:water-near] ".Length).Trim(), out var result))
			{
				return false;
			}
			if (result != -1)
			{
				water = (WaterType)result;
			}
			return true;
		}

		public static string BuildWaterPlaces(int water, int regionSlot, WaterType kind, IReadOnlyList<float> xs, IReadOnlyList<float> zs, int from, int count, bool others = false)
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			List<string> list = new List<string>();
			for (int i = from; i < from + count && i < xs.Count; i++)
			{
				list.Add(Math.Round(xs[i]).ToString(invariantCulture) + "," + Math.Round(zs[i]).ToString(invariantCulture));
			}
			string obj = (others ? "[DeepRising:water-not] " : "[DeepRising:water] ");
			string separator = '|'.ToString();
			string[] obj2 = new string[4]
			{
				water.ToString(invariantCulture),
				regionSlot.ToString(invariantCulture),
				null,
				null
			};
			int num = (int)kind;
			obj2[2] = num.ToString(invariantCulture);
			obj2[3] = string.Join(';'.ToString(), list);
			return obj + string.Join(separator, obj2);
		}

		public static bool TryParseWaterPlaces(string message, out int water, out int regionSlot, out WaterType kind, out float[] xs, out float[] zs, out bool others)
		{
			water = (regionSlot = 0);
			kind = WaterType.Shallow;
			xs = (zs = null);
			others = message?.StartsWith("[DeepRising:water-not] ", StringComparison.Ordinal) ?? false;
			if (message == null || (!others && !message.StartsWith("[DeepRising:water] ", StringComparison.Ordinal)))
			{
				return false;
			}
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string[] array = message.Substring((others ? "[DeepRising:water-not] " : "[DeepRising:water] ").Length).Trim().Split('|');
			if (array.Length != 4 || !int.TryParse(array[0], out water) || !int.TryParse(array[1], out regionSlot) || !int.TryParse(array[2], out var result))
			{
				return false;
			}
			string[] array2 = array[3].Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			float[] array3 = new float[array2.Length];
			float[] array4 = new float[array2.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				string[] array5 = array2[i].Split(',');
				if (array5.Length != 2 || !float.TryParse(array5[0], NumberStyles.Float, invariantCulture, out array3[i]) || !float.TryParse(array5[1], NumberStyles.Float, invariantCulture, out array4[i]))
				{
					return false;
				}
			}
			kind = (WaterType)result;
			xs = array3;
			zs = array4;
			return true;
		}

		public static string BuildWaterFish(int regionSlot, WaterType water, IEnumerable<string> items)
		{
			string separator = '|'.ToString();
			string[] obj = new string[3]
			{
				regionSlot.ToString(),
				null,
				null
			};
			int num = (int)water;
			obj[1] = num.ToString();
			obj[2] = string.Join(';'.ToString(), items);
			return "[DeepRising:water-fish] " + string.Join(separator, obj);
		}

		public static bool TryParseWaterFish(string message, out int regionSlot, out WaterType water, out string[] items)
		{
			regionSlot = 0;
			water = WaterType.Shallow;
			items = null;
			if (message == null || !message.StartsWith("[DeepRising:water-fish] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:water-fish] ".Length).Trim().Split('|');
			if (array.Length != 3 || !int.TryParse(array[0], out regionSlot) || !int.TryParse(array[1], out var result))
			{
				return false;
			}
			water = (WaterType)result;
			items = array[2].Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			return true;
		}

		public static string BuildCodexCommand(string language)
		{
			return ".fish codexdata " + language;
		}

		public static string BuildCodexRegion(CodexRegionEntry region)
		{
			return "[DeepRising:cx-region] " + string.Join('|'.ToString(), region.Biome, Clean(region.Name), region.Known.ToString(), region.Total.ToString(), region.Complete ? "1" : "0", region.BonusPoints.ToString());
		}

		public static bool TryParseCodexRegion(string message, out CodexRegionEntry region)
		{
			region = default(CodexRegionEntry);
			if (message == null || !message.StartsWith("[DeepRising:cx-region] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:cx-region] ".Length).Split('|');
			if (array.Length != 6 || !int.TryParse(array[2], out var result) || !int.TryParse(array[3], out var result2) || !int.TryParse(array[5], out var result3))
			{
				return false;
			}
			region = new CodexRegionEntry
			{
				Biome = array[0],
				Name = array[1],
				Known = result,
				Total = result2,
				Complete = (array[4] == "1"),
				BonusPoints = result3
			};
			return true;
		}

		public static List<string> BuildCodexFishLines(string biome, IEnumerable<CodexFishEntry> fish)
		{
			List<string> list = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			foreach (CodexFishEntry item in fish)
			{
				string separator = '~'.ToString();
				string[] obj = new string[9]
				{
					item.Id,
					item.Item,
					CleanRecord(item.Name),
					null,
					null,
					null,
					null,
					null,
					null
				};
				int rarity = (int)item.Rarity;
				obj[3] = rarity.ToString();
				obj[4] = item.Catches.ToString();
				obj[5] = item.BestQuality.ToString();
				obj[6] = item.FirstCaught ?? string.Empty;
				obj[7] = item.TrophyQuality.ToString();
				obj[8] = CleanRecord(item.Needs);
				string text = string.Join(separator, obj);
				if (stringBuilder.Length > 0 && Encoding.UTF8.GetByteCount(stringBuilder.ToString()) + Encoding.UTF8.GetByteCount(text) + 1 > 380)
				{
					list.Add("[DeepRising:cx-fish] " + biome + "|" + stringBuilder);
					stringBuilder.Clear();
				}
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(text);
			}
			if (stringBuilder.Length > 0)
			{
				list.Add("[DeepRising:cx-fish] " + biome + "|" + stringBuilder);
			}
			return list;
		}

		public static bool TryParseCodexFish(string message, out string biome, out List<CodexFishEntry> fish)
		{
			biome = null;
			fish = null;
			if (message == null || !message.StartsWith("[DeepRising:cx-fish] ", StringComparison.Ordinal))
			{
				return false;
			}
			string text = message.Substring("[DeepRising:cx-fish] ".Length);
			int num = text.IndexOf('|');
			if (num <= 0)
			{
				return false;
			}
			biome = text.Substring(0, num);
			fish = new List<CodexFishEntry>();
			string[] array = text.Substring(num + 1).Split(';');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split('~');
				if (array2.Length != 9 || !int.TryParse(array2[3], out var result) || !int.TryParse(array2[4], out var result2) || !int.TryParse(array2[5], out var result3) || !int.TryParse(array2[7], out var result4))
				{
					return false;
				}
				fish.Add(new CodexFishEntry
				{
					Id = array2[0],
					Item = array2[1],
					Name = array2[2],
					Rarity = (FishRarity)result,
					Catches = result2,
					BestQuality = result3,
					FirstCaught = array2[6],
					TrophyQuality = result4,
					Needs = array2[8]
				});
			}
			return true;
		}

		public static string BuildPageCommand(string language)
		{
			return ".fish pagedata " + language;
		}

		public static string BuildPageRow(PageRow row)
		{
			string separator = '|'.ToString();
			string[] obj = new string[8]
			{
				Clean(row.Page),
				null,
				null,
				null,
				null,
				null,
				null,
				null
			};
			int style = (int)row.Style;
			obj[1] = style.ToString();
			obj[2] = Clean(row.Icon);
			obj[3] = Clean(row.First);
			obj[4] = Clean(row.Second);
			obj[5] = Clean(row.Third);
			obj[6] = Clean(row.Button);
			obj[7] = Clean(row.Command);
			return "[DeepRising:pg-row] " + string.Join(separator, obj);
		}

		public static bool TryParsePageRow(string message, out PageRow row)
		{
			row = default(PageRow);
			if (message == null || !message.StartsWith("[DeepRising:pg-row] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:pg-row] ".Length).Split('|');
			if (array.Length != 8 || !int.TryParse(array[1], out var result))
			{
				return false;
			}
			row = new PageRow
			{
				Page = array[0],
				Style = (PageRowStyle)result,
				Icon = array[2],
				First = array[3],
				Second = array[4],
				Third = array[5],
				Button = array[6],
				Command = array[7]
			};
			return true;
		}

		public static string BuildCellCommand(string language)
		{
			return ".fish celldata " + language;
		}

		public static string BuildCellInfo(string iconItem, IEnumerable<string> lines)
		{
			List<string> list = new List<string>();
			foreach (string line in lines)
			{
				list.Add(CleanRecord(line));
			}
			return "[DeepRising:cell] " + Clean(iconItem) + "|" + string.Join(';'.ToString(), list);
		}

		public static bool TryParseCellInfo(string message, out string iconItem, out string text)
		{
			iconItem = null;
			text = null;
			if (message == null || !message.StartsWith("[DeepRising:cell] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:cell] ".Length).Split('|');
			if (array.Length != 2)
			{
				return false;
			}
			iconItem = array[0];
			text = array[1].Replace(';', '\n');
			return true;
		}

		public static string BuildHaulStart(HaulGameRules rules, string fishItem, string hint, string pullLabel, string letGoLabel)
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			return "[DeepRising:haul] " + string.Join('|'.ToString(), rules.Seed.ToString(invariantCulture), rules.Seconds.ToString("R", invariantCulture), rules.SlackSeconds.ToString("R", invariantCulture), rules.Zone.ToString("R", invariantCulture), rules.FishSpeed.ToString("R", invariantCulture), rules.TimeLimit.ToString("R", invariantCulture), Clean(fishItem), Clean(hint), Clean(pullLabel), Clean(letGoLabel));
		}

		public static bool TryParseHaulStart(string message, out HaulGameRules rules, out string fishItem, out string hint, out string pullLabel, out string letGoLabel)
		{
			rules = null;
			fishItem = (hint = (pullLabel = (letGoLabel = null)));
			if (message == null || !message.StartsWith("[DeepRising:haul] ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Substring("[DeepRising:haul] ".Length).Split('|');
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			NumberStyles style =