Decompiled source of Megabonk Wildforge Mod v0.3.0

BepInEx/plugins/Wildforge/Wildforge.Megabonk.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Json;
using Actors.Enemies;
using Assets.Scripts.Actors;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Actors.Player;
using Assets.Scripts.Game.Combat.EnemyDebuffs;
using Assets.Scripts.Inventory__Items__Pickups;
using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive;
using Assets.Scripts.Inventory__Items__Pickups.Chests;
using Assets.Scripts.Inventory__Items__Pickups.Items;
using Assets.Scripts.Inventory__Items__Pickups.Items.ItemImplementations;
using Assets.Scripts.Inventory__Items__Pickups.Stats;
using Assets.Scripts.Inventory__Items__Pickups.Weapons;
using Assets.Scripts.Managers;
using Assets.Scripts.Menu.Shop;
using Assets.Scripts.Saves___Serialization.Progression.Achievements;
using Assets.Scripts.Saves___Serialization.Progression.Unlocks;
using Assets.Scripts._Data.MapsAndStages;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Bindings;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Wildforge.Megabonk")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0")]
[assembly: AssemblyProduct("Wildforge.Megabonk")]
[assembly: AssemblyTitle("Wildforge.Megabonk")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
[module: UnverifiableCode]
namespace Wildforge.Megabonk;

[HarmonyPatch]
internal static class BloodBank
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		yield return AccessTools.Method(typeof(Enemy), "DamageFromPlayerWeapon", (Type[])null, (Type[])null);
		yield return AccessTools.Method(typeof(Enemy), "DamageFromPlayerOther", (Type[])null, (Type[])null);
	}

	private static void Prefix(Enemy __instance, DamageContainer dc, out float __state)
	{
		__state = Math.Max(0f, __instance.hp);
		if (!Effects.ExtraDamage)
		{
			float num = 1f;
			if (Effects.Condition("air"))
			{
				num += Effects.Value("airDamage");
			}
			MyPlayer instance = MyPlayer.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerInventory inventory = instance.inventory;
				obj = ((inventory != null) ? inventory.playerHealth : null);
			}
			PlayerHealth val = (PlayerHealth)obj;
			if (val != null)
			{
				num += Effects.Value("berserk") * (1f - (float)val.hp / (float)Math.Max(1, val.maxHp));
			}
			if (CombatEffects.IsBoss(__instance))
			{
				num *= Effects.Value("bossDamage");
			}
			num *= SkillCompatibility.Power(SkillCompatibility.Family(dc.damageSource));
			dc.damage *= num;
			if (!CombatEffects.IsBoss(__instance) && Effects.Value("execute") > 0f && __instance.hp / __instance.maxHp < Math.Min(0.35f, Effects.Value("execute")))
			{
				dc.damage += __instance.hp;
			}
		}
	}

	private static void Postfix(Enemy __instance, DamageContainer dc, float __state)
	{
		float actual = Math.Clamp(__state - Math.Max(0f, __instance.hp), 0f, __state);
		CombatEffects.OnHit(__instance, dc, actual);
	}
}
[HarmonyPatch(typeof(Enemy), "EnemyDied", new Type[] { typeof(DamageContainer) })]
internal static class KillEffects
{
	private static void Prefix(Enemy __instance, DamageContainer dc)
	{
		CombatEffects.OnKill(__instance, ((dc != null) ? dc.damageSource : null) ?? "");
	}
}
[HarmonyPatch(typeof(PlayerHealth), "Damage")]
internal static class HurtEffects
{
	private static void Prefix(PlayerHealth __instance, out float __state)
	{
		__state = __instance.hp;
	}

	private static void Postfix(PlayerHealth __instance, float __state)
	{
		CombatEffects.OnHurt(Math.Max(0f, __state - (float)__instance.hp));
	}
}
[HarmonyPatch(typeof(PlayerHealth), "PlayerDied")]
internal static class ReviveEffect
{
	private static bool Prefix()
	{
		return !CombatEffects.TryRevive();
	}
}
[HarmonyPatch(typeof(ChestOpening), "OpenChest")]
internal static class ChestHeal
{
	private static void Postfix()
	{
		CombatEffects.Heal(Effects.Value("chestHeal"));
	}
}
[HarmonyPatch(typeof(WeaponBase), "Use")]
internal static class TurretWeapons
{
	private static bool Prefix(WeaponBase __instance)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected I4, but got Unknown
		if (Catalog.WeaponsById.TryGetValue((int)__instance.weaponData.eWeapon, out var value))
		{
			return !value.Turret;
		}
		return true;
	}
}
[HarmonyPatch(typeof(InteractableChest), "GetPrice")]
internal static class FreeKeys
{
	private static readonly Dictionary<IntPtr, float> Rolls = new Dictionary<IntPtr, float>();

	private static void Postfix(InteractableChest __instance, ref int __result)
	{
		if (!Rolls.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out var value))
		{
			value = (Rolls[((Il2CppObjectBase)__instance).Pointer] = Random.value);
		}
		if (value < Math.Clamp(Effects.Value("keyPower"), 0f, 0.75f))
		{
			__result = 0;
		}
	}
}
[HarmonyPatch(typeof(AchievementTracker), "OnPotBroken")]
internal static class PotGold
{
	private static void Postfix()
	{
		MyPlayer instance = MyPlayer.Instance;
		PlayerInventory val = ((instance != null) ? instance.inventory : null);
		if (val != null && Effects.Value("potGold") > 1f)
		{
			val.ChangeGold((int)Math.Ceiling((Effects.Value("potGold") - 1f) * 5f));
		}
	}
}
internal sealed class EffectDef
{
	public string Key { get; set; }

	public float Amount { get; set; }

	public string Mode { get; set; } = "add";
}
internal sealed class Entry
{
	public string Id { get; set; }

	public string Name { get; set; }

	public string Title { get; set; }

	public string Description { get; set; }

	public string Family { get; set; }

	public string Kind { get; set; }

	public int Rarity { get; set; }

	public string Asset { get; set; }

	public string Portrait { get; set; }

	public string Weapon { get; set; }

	public string Perk { get; set; }

	public int RuntimeId { get; set; }

	public List<EffectDef> Effects { get; set; } = new List<EffectDef>();

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

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

	public float Range { get; set; }

	public bool Turret { get; set; }

	public string TurretType { get; set; }

	public string Archetype { get; set; }

	public Dictionary<string, JsonElement> Modifiers { get; set; } = new Dictionary<string, JsonElement>();

	public int Biome { get; set; }

	public int Species { get; set; }

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

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

	public float Height { get; set; }

	public float Radius { get; set; }

	public int Weight { get; set; }

	public string Behavior { get; set; }

	public bool Flying { get; set; }

	public bool Boss { get; set; }

	public int Realm { get; set; }
}
internal sealed class AugmentDef
{
	public string Condition { get; set; }

	public string Stat { get; set; }

	public string Mode { get; set; }

	public string When { get; set; }

	public string Label { get; set; }
}
internal sealed class Catalog
{
	internal static Catalog Data;

	internal static readonly Dictionary<int, Entry> HeroesById = new Dictionary<int, Entry>();

	internal static readonly Dictionary<int, Entry> CardsById = new Dictionary<int, Entry>();

	internal static readonly Dictionary<int, Entry> WeaponsById = new Dictionary<int, Entry>();

	internal static readonly Dictionary<int, Entry> EnemiesById = new Dictionary<int, Entry>();

	public List<Entry> Heroes { get; set; }

	public List<Entry> Cards { get; set; }

	public List<Entry> Weapons { get; set; }

	public List<Entry> Enemies { get; set; }

	public Dictionary<string, AugmentDef> Augments { get; set; }

	public Dictionary<string, float> Stats { get; set; }

	public Dictionary<string, string> Labels { get; set; }

	public List<string> Icons { get; set; }

	internal static void Load()
	{
		if (Data != null)
		{
			return;
		}
		Data = JsonSerializer.Deserialize<Catalog>(File.ReadAllText(Path.Combine(Plugin.AssetDirectory, "wildforge-catalog.json")), new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true
		});
		foreach (Entry hero in Data.Heroes)
		{
			HeroesById.Add(hero.RuntimeId, hero);
		}
		foreach (Entry card in Data.Cards)
		{
			CardsById.Add(card.RuntimeId, card);
		}
		foreach (Entry weapon in Data.Weapons)
		{
			WeaponsById.Add(weapon.RuntimeId, weapon);
		}
		foreach (Entry enemy in Data.Enemies)
		{
			EnemiesById.Add(enemy.RuntimeId, enemy);
		}
	}

	internal static string Describe(Entry entry)
	{
		if (!string.IsNullOrEmpty(entry.Description))
		{
			return entry.Description;
		}
		if (entry.Effects.Count == 0)
		{
			return entry.Family + " weapon from Wildforge.";
		}
		return string.Join("\n", entry.Effects.Select(delegate(EffectDef e)
		{
			string value = Data.Labels.GetValueOrDefault(e.Key, e.Key);
			string value2 = "";
			string mode = e.Mode;
			if (Data.Augments.TryGetValue(e.Key, out var value3))
			{
				value = value3.Label;
				value2 = " " + value3.When;
				mode = value3.Mode;
			}
			int num2;
			if (!(mode == "multiply"))
			{
				string key = e.Key;
				int num;
				switch (key)
				{
				default:
					num = ((!(key == "keyPower")) ? 1 : 0);
					break;
				case "crit":
				case "dodge":
				case "freeze":
				case "lifesteal":
				case "luck":
				case "discount":
					num = 0;
					break;
				}
				num2 = ((num == 0) ? 1 : 0);
			}
			else
			{
				num2 = 1;
			}
			bool flag = (byte)num2 != 0;
			return $"+{(flag ? (e.Amount * 100f) : e.Amount):0.##}{(flag ? "%" : "")} {value}{value2} per stack";
		}));
	}
}
internal static class CombatEffects
{
	private sealed class Turret
	{
		internal GameObject Model;

		internal Vector3 Position;

		internal Entry Weapon;

		internal float Born;

		internal float NextShot;
	}

	private sealed class Flower
	{
		internal GameObject Model;

		internal Vector3 Position;

		internal float Born;
	}

	private sealed class Pool
	{
		internal Vector3 Position;

		internal float Until;

		internal float Damage;
	}

	private static readonly List<Pool> Pools = new List<Pool>();

	private static int snapshotFrame = -1;

	private static Enemy[] snapshot = Array.Empty<Enemy>();

	private static float lastTick;

	private static float coinScan;

	private static bool slamming;

	private static bool ownsInvincibility;

	private static readonly List<Turret> Turrets = new List<Turret>();

	private static readonly List<Flower> Flowers = new List<Flower>();

	private static float pulse;

	private static float nextTurret;

	private static float nextFlower;

	private static float lastGold;

	private static float walkMoney;

	private static int revivesUsed;

	private static float healingRemainder;

	private static Vector3 previousPosition;

	private static bool grounded = true;

	private static bool dashing;

	private static float nextDash;

	private static float dashUntil;

	private static float reviveUntil;

	internal static bool HasFlowers => Flowers.Count > 0;

	internal static bool HasTurrets => Turrets.Count > 0;

	internal static bool NearFlower(Vector3 p)
	{
		//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)
		return Flowers.Any(delegate(Flower f)
		{
			//IL_000f: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)f.Model != (Object)null)
			{
				Vector3 val = f.Position - p;
				return ((Vector3)(ref val)).sqrMagnitude < 64f;
			}
			return false;
		});
	}

	internal static bool NearTurret(Vector3 p)
	{
		//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)
		return Turrets.Any(delegate(Turret t)
		{
			//IL_000f: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t.Model != (Object)null)
			{
				Vector3 val = t.Position - p;
				return ((Vector3)(ref val)).sqrMagnitude < 64f;
			}
			return false;
		});
	}

	internal static void Heal(float amount)
	{
		MyPlayer instance = MyPlayer.Instance;
		object obj;
		if (instance == null)
		{
			obj = null;
		}
		else
		{
			PlayerInventory inventory = instance.inventory;
			obj = ((inventory != null) ? inventory.playerHealth : null);
		}
		PlayerHealth val = (PlayerHealth)obj;
		if (val == null || val.IsDead() || amount <= 0f)
		{
			return;
		}
		if (val.hp >= val.maxHp)
		{
			healingRemainder = 0f;
			return;
		}
		healingRemainder += Math.Min(amount, val.maxHp - val.hp);
		int num = (int)healingRemainder;
		if (num > 0)
		{
			val.Heal((float)Math.Min(num, val.maxHp - val.hp), false);
			healingRemainder -= num;
		}
	}

	internal static void Reset()
	{
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		foreach (Turret turret in Turrets)
		{
			if ((Object)(object)turret.Model != (Object)null)
			{
				Object.Destroy((Object)(object)turret.Model);
			}
		}
		foreach (Flower flower in Flowers)
		{
			if ((Object)(object)flower.Model != (Object)null)
			{
				Object.Destroy((Object)(object)flower.Model);
			}
		}
		Turrets.Clear();
		Flowers.Clear();
		Pools.Clear();
		snapshotFrame = -1;
		lastTick = Time.time;
		coinScan = 0f;
		slamming = (ownsInvincibility = false);
		pulse = (nextTurret = (nextFlower = (walkMoney = (nextDash = (dashUntil = (reviveUntil = 0f))))));
		lastGold = 0f;
		revivesUsed = 0;
		healingRemainder = 0f;
		previousPosition = Vector3.zero;
		grounded = true;
		dashing = false;
	}

	internal static Enemy[] Enemies()
	{
		if (snapshotFrame == Time.frameCount)
		{
			return snapshot;
		}
		List<Enemy> list = new List<Enemy>();
		if ((Object)(object)EnemyManager.Instance != (Object)null)
		{
			Enumerator<uint, Enemy> enumerator = EnemyManager.Instance.enemies.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<uint, Enemy> current = enumerator.Current;
				if ((Object)(object)current.Value != (Object)null && current.Value.hp > 0f)
				{
					list.Add(current.Value);
				}
			}
		}
		snapshotFrame = Time.frameCount;
		return snapshot = list.ToArray();
	}

	private static Enemy[] Nearby(Vector3 center, float radius, int limit = 20)
	{
		//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)
		return Enemies().Where(delegate(Enemy e)
		{
			//IL_0006: 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_0011: 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)
			Vector3 val = ((Component)e).transform.position - center;
			return ((Vector3)(ref val)).sqrMagnitude < radius * radius;
		}).OrderBy(delegate(Enemy e)
		{
			//IL_0006: 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_0011: 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)
			Vector3 val = ((Component)e).transform.position - center;
			return ((Vector3)(ref val)).sqrMagnitude;
		}).Take(limit)
			.ToArray();
	}

	internal static bool IsBoss(Enemy enemy)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Expected I4, but got Unknown
		EnemyManager instance = EnemyManager.Instance;
		if (instance == null || !instance.stageBosses.Contains(enemy))
		{
			if (Catalog.EnemiesById.TryGetValue((int)enemy.enemyData.enemyName, out var value))
			{
				return value.Boss;
			}
			return false;
		}
		return true;
	}

	internal static void Deal(Enemy enemy, float damage, string source = "pulse")
	{
		//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_004d: Expected O, but got Unknown
		if ((Object)(object)enemy == (Object)null || enemy.hp <= 0f || damage <= 0f)
		{
			return;
		}
		bool extraDamage = Effects.ExtraDamage;
		Effects.ExtraDamage = true;
		try
		{
			enemy.DamageFromPlayerOther(new DamageContainer(0f, "wildforge_" + source)
			{
				damage = damage
			});
		}
		finally
		{
			Effects.ExtraDamage = extraDamage;
		}
	}

	internal static void Burst(Vector3 position, float damage, float radius, string source)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		Enemy[] array = Nearby(position, radius);
		for (int i = 0; i < array.Length; i++)
		{
			Deal(array[i], damage, source);
		}
	}

	internal static void Debuff(Enemy enemy, EDebuff type, float damage, float seconds)
	{
		//IL_0001: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		enemy.AddDebuff(type, new DamageContainer(1f, "wildforge_status")
		{
			damage = damage
		}, seconds, 1);
	}

	internal static void OnHit(Enemy enemy, DamageContainer dc, float actual)
	{
		//IL_01ca: 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_0376: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: 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_0529: Unknown result type (might be due to invalid IL or missing references)
		//IL_0622: Unknown result type (might be due to invalid IL or missing references)
		//IL_0671: Unknown result type (might be due to invalid IL or missing references)
		MyPlayer instance = MyPlayer.Instance;
		PlayerInventory obj = ((instance != null) ? instance.inventory : null);
		if (((obj != null) ? obj.playerHealth : null) == null || actual <= 0f)
		{
			return;
		}
		float num = Math.Clamp(Effects.Value("lifesteal"), 0f, 0.4f);
		if (num > 0f)
		{
			Heal(actual * num);
		}
		if (Effects.ExtraDamage || enemy.hp <= 0f)
		{
			return;
		}
		SkillCompatibility.Pierce(enemy, dc, actual);
		if (Effects.Value("poison") > 0f)
		{
			Debuff(enemy, (EDebuff)1, Effects.Value("poison"), 4f);
		}
		if (Effects.Value("burn") > 0f)
		{
			Debuff(enemy, (EDebuff)4, Effects.Value("burn"), 3f);
		}
		if (Random.value < Effects.Value("freeze"))
		{
			Debuff(enemy, (EDebuff)2, 0f, 2f);
		}
		if (Random.value < Math.Clamp(Effects.Value("stun"), 0f, 1f))
		{
			Debuff(enemy, (EDebuff)8, 0f, 0.4f);
		}
		if (Random.value < Effects.Value("blind") + Effects.Value("banana"))
		{
			Debuff(enemy, (EDebuff)8, 0f, 0.6f);
		}
		if (Effects.Value("slow") > 0f)
		{
			SkillCompatibility.Slow(enemy, Effects.Value("slow"), 4f);
		}
		int num2 = (int)Math.Clamp(Effects.Value("chain"), 0f, 8f);
		foreach (Enemy item in (from e in Nearby(((Component)enemy).transform.position, 8f, num2 + 1)
			where ((Il2CppObjectBase)e).Pointer != ((Il2CppObjectBase)enemy).Pointer
			select e).Take(num2))
		{
			Deal(item, actual * 0.35f, "chain");
		}
		float num3 = Math.Clamp(Effects.Value("splash"), 0f, 2f);
		if (num3 > 0f)
		{
			foreach (Enemy item2 in from e in Nearby(((Component)enemy).transform.position, 3f + num3 * 2f)
				where ((Il2CppObjectBase)e).Pointer != ((Il2CppObjectBase)enemy).Pointer
				select e)
			{
				Deal(item2, actual * num3 * 0.35f, "splash");
			}
		}
		if (Effects.Value("boomerang") > 0f)
		{
			Deal(enemy, actual * Math.Min(0.5f, Effects.Value("boomerang")) * 0.3f, "return");
		}
		string text = SkillCompatibility.Family(dc.damageSource);
		if (text == "harpoon" && !IsBoss(enemy) && Effects.Value("harpoonPull") > 0f)
		{
			Rigidbody rb = enemy.rb;
			Vector3 val = ((Component)MyPlayer.Instance).transform.position - ((Component)enemy).transform.position;
			rb.AddForce(((Vector3)(ref val)).normalized * Effects.Value("harpoonPull") * 8f, (ForceMode)2);
		}
		if (text == "horn")
		{
			Debuff(enemy, (EDebuff)8, 0f, 0.35f + Effects.Value("hornStun"));
		}
		if (text == "bubble")
		{
			SkillCompatibility.Slow(enemy, 0.7f, 1.5f * Effects.Value("bubbleTime"));
			Debuff(enemy, (EDebuff)2, 0f, Math.Min(3f, 1.5f * Effects.Value("bubbleTime")));
		}
		Entry entry = Catalog.Data.Weapons.FirstOrDefault((Entry w) => dc.damageSource == "wildforge_weapon_" + w.Id);
		if (entry == null)
		{
			return;
		}
		if (entry.Modifiers.TryGetValue("payload", out var value))
		{
			switch (value.GetString())
			{
			case "poison":
				Debuff(enemy, (EDebuff)1, actual * 0.2f, 3f);
				break;
			case "fire":
				Debuff(enemy, (EDebuff)4, actual * 0.2f, 3f);
				break;
			case "ice":
			case "bubble":
				Debuff(enemy, (EDebuff)2, 0f, 1f);
				break;
			}
		}
		if (entry.Modifiers.TryGetValue("extraPierce", out var value2))
		{
			foreach (Enemy item3 in from e in Nearby(((Component)enemy).transform.position, 5f, value2.GetInt32() + 1)
				where ((Il2CppObjectBase)e).Pointer != ((Il2CppObjectBase)enemy).Pointer
				select e)
			{
				Deal(item3, actual * 0.2f, "variant_pierce");
			}
		}
		if (entry.Modifiers.TryGetValue("stunBonus", out var value3))
		{
			Debuff(enemy, (EDebuff)8, 0f, value3.GetSingle());
		}
		if (entry.Modifiers.TryGetValue("returning", out var value4) && value4.ValueKind == JsonValueKind.True)
		{
			Deal(enemy, actual * 0.2f, "variant_return");
		}
		if (entry.Modifiers.TryGetValue("sweepDot", out var value5))
		{
			Burst(((Component)enemy).transform.position, actual * 0.1f, 2f + 2f * (1f - value5.GetSingle()), "wide_sweep");
		}
		if (entry.Modifiers.TryGetValue("coneDot", out var value6))
		{
			Burst(((Component)enemy).transform.position, actual * 0.1f, 2f + 3f * (1f - value6.GetSingle()), "wide_cone");
		}
	}

	internal static void OnKill(Enemy enemy, string source = "")
	{
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		Effects.KilledAt = Time.time;
		MyPlayer instance = MyPlayer.Instance;
		if (((instance != null) ? instance.inventory : null) != null)
		{
			if (Random.value < Math.Clamp(Effects.Value("salvage"), 0f, 1f))
			{
				Heal(4f);
			}
			if (Effects.Value("explosion") > 0f && source != "wildforge_kill_explosion")
			{
				Burst(((Component)enemy).transform.position, Effects.Value("explosion"), 4f, "kill_explosion");
			}
			if (Effects.Value("pools") > 0f)
			{
				Pools.Add(new Pool
				{
					Position = ((Component)enemy).transform.position,
					Until = Time.time + 5f,
					Damage = Effects.Value("pools")
				});
			}
		}
	}

	internal static void OnHurt(float amount)
	{
		Effects.HurtAt = Time.time;
		MyPlayer instance = MyPlayer.Instance;
		PlayerInventory val = ((instance != null) ? instance.inventory : null);
		if (val != null && Effects.Value("hurtGold") > 0f)
		{
			val.gold += amount * Effects.Value("hurtGold");
		}
	}

	internal static bool TryRevive()
	{
		MyPlayer instance = MyPlayer.Instance;
		object obj;
		if (instance == null)
		{
			obj = null;
		}
		else
		{
			PlayerInventory inventory = instance.inventory;
			obj = ((inventory != null) ? inventory.playerHealth : null);
		}
		PlayerHealth val = (PlayerHealth)obj;
		if (val == null || revivesUsed >= (int)Math.Clamp(Effects.Value("revive"), 0f, 4f))
		{
			return false;
		}
		revivesUsed++;
		val.hp = Math.Max(1, (int)((float)val.maxHp * 0.6f));
		OwnInvincibility(instance);
		reviveUntil = Time.time + 3f;
		return true;
	}

	internal static void Tick(MyPlayer player, float dt)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: 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_0205: 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_039a: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Expected I4, but got Unknown
		//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_070f: Expected I4, but got Unknown
		//IL_02df: 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_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0559: Unknown result type (might be due to invalid IL or missing references)
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_0448: Unknown result type (might be due to invalid IL or missing references)
		//IL_0452: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: Unknown result type (might be due to invalid IL or missing references)
		//IL_0483: Unknown result type (might be due to invalid IL or missing references)
		//IL_0488: Unknown result type (might be due to invalid IL or missing references)
		//IL_0776: Unknown result type (might be due to invalid IL or missing references)
		//IL_0782: Expected I4, but got Unknown
		//IL_081f: Unknown result type (might be due to invalid IL or missing references)
		//IL_084b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0850: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0964: Unknown result type (might be due to invalid IL or missing references)
		//IL_0967: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a56: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a70: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a9b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ac6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b11: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bd1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0be1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bed: Expected O, but got Unknown
		dt = Math.Clamp(Time.time - lastTick, 0f, 0.5f);
		lastTick = Time.time;
		PlayerInventory inventory = player.inventory;
		PlayerMovement playerMovement = player.playerMovement;
		Vector3 position = ((Component)player).transform.position;
		float num = ((previousPosition == Vector3.zero) ? 0f : Vector3.Distance(position, previousPosition));
		previousPosition = position;
		if (num < 20f)
		{
			walkMoney += num * Effects.Value("walkGold");
		}
		if (walkMoney >= 1f)
		{
			inventory.gold += MathF.Floor(walkMoney);
			walkMoney %= 1f;
		}
		lastGold = inventory.gold;
		bool flag = playerMovement == null || playerMovement.grounded;
		bool flag2 = (playerMovement != null && playerMovement.isDashing) || Time.time < dashUntil;
		if (flag2 && !dashing)
		{
			Burst(position, Effects.Value("dashBlast"), 4f, "dash");
			if (Effects.Value("burrow") > 0f)
			{
				Burst(position, Effects.Value("burrow") * 25f, 4f, "burrow");
			}
		}
		if (!flag && grounded)
		{
			Burst(position, Effects.Value("jumpBlast"), 3f, "jump");
			if (Effects.Value("jumpShield") > 0f)
			{
				inventory.playerHealth.shield = Math.Min(inventory.playerHealth.maxShield + Effects.Value("jumpShield"), inventory.playerHealth.shield + Effects.Value("jumpShield"));
			}
		}
		if (flag && !grounded)
		{
			Heal(Effects.Value("landingHeal"));
			if (slamming)
			{
				Effects.SlamAt = Time.time;
				Heal(Effects.Value("slamHeal"));
				Burst(position, Effects.Value("damage") * 2f * Effects.Value("slamPower"), 4f * Effects.Value("slamRadius"), "slam");
				Enemy[] array = Nearby(position, 4f * Effects.Value("slamRadius"));
				foreach (Enemy enemy in array)
				{
					if (Effects.Value("slamFire") > 0f)
					{
						Debuff(enemy, (EDebuff)4, Effects.Value("slamFire"), 3f);
					}
					if (Effects.Value("slamPoison") > 0f)
					{
						Debuff(enemy, (EDebuff)1, Effects.Value("slamPoison"), 4f);
					}
				}
				if ((Object)(object)playerMovement != (Object)null && Effects.Value("bounceJump") > 0f)
				{
					playerMovement.rb.AddForce(Vector3.up * 8.5f * MathF.Sqrt(1f + Effects.Value("bounceJump")), (ForceMode)2);
				}
			}
			slamming = false;
		}
		if (Time.time < reviveUntil || (dashUntil > 0f && Time.time < dashUntil + 0.3f + Effects.Value("ghost")))
		{
			OwnInvincibility(player);
		}
		else if (ownsInvincibility)
		{
			player.isInvincible = false;
			ownsInvincibility = false;
		}
		grounded = flag;
		dashing = flag2;
		Enumerator<EWeapon, WeaponBase> enumerator = inventory.weaponInventory.weapons.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<EWeapon, WeaponBase> current = enumerator.Current;
			if (Catalog.WeaponsById.TryGetValue((int)current.Key, out var value) && value.Turret && Time.time >= nextTurret)
			{
				nextTurret = Time.time + Math.Max(2f, Effects.Value("turretLife") * 0.35f);
				GameObject val = Object.Instantiate<GameObject>(DuckModel.Prefab(File.Exists(Path.Combine(Plugin.AssetDirectory, "weapon_" + value.Id + ".glb")) ? ("weapon_" + value.Id) : "weapon_turret"));
				val.transform.position = player.feet.position + Vector3.right * 1.5f;
				val.SetActive(true);
				Turrets.Add(new Turret
				{
					Model = val,
					Position = val.transform.position,
					Weapon = value,
					Born = Time.time
				});
			}
		}
		Turret[] array2 = Turrets.ToArray();
		foreach (Turret turret in array2)
		{
			if (Time.time - turret.Born > Effects.Value("turretLife"))
			{
				if ((Object)(object)turret.Model != (Object)null)
				{
					Object.Destroy((Object)(object)turret.Model);
				}
				Turrets.Remove(turret);
				continue;
			}
			if (Time.time >= turret.NextShot)
			{
				turret.NextShot = Time.time + 1f / Math.Max(0.2f, Effects.Value("turretRate") * turret.Weapon.Rate);
				Enemy val2 = Nearby(turret.Position, 18f * Effects.Value("turretRange"), 1).FirstOrDefault();
				if ((Object)(object)val2 != (Object)null)
				{
					Deal(val2, Effects.Value("damage") * Effects.Value("turretDamage") * turret.Weapon.Damage, "turret");
					if (turret.Weapon.Id.Contains("fire"))
					{
						Debuff(val2, (EDebuff)4, Effects.Value("damage") * 0.2f, 3f);
					}
					if (turret.Weapon.Id.Contains("poison"))
					{
						Debuff(val2, (EDebuff)1, Effects.Value("damage") * 0.2f, 3f);
					}
					if (turret.Weapon.Id.Contains("ice"))
					{
						Debuff(val2, (EDebuff)2, 0f, 1f);
					}
					if (turret.Weapon.Modifiers.TryGetValue("payload", out var value2))
					{
						Debuff(val2, (EDebuff)((value2.GetString() == "poison") ? 1 : ((value2.GetString() == "fire") ? 4 : 2)), Effects.Value("damage") * 0.2f, 2f);
					}
				}
			}
			if (Vector3.Distance(position, turret.Position) < 4f && Effects.Value("repair") > 0f)
			{
				Heal(Effects.Value("repair") * dt);
			}
		}
		if (Catalog.HeroesById.TryGetValue((int)inventory.characterData.eCharacter, out var hero) && hero.TurretType != null && Time.time >= nextTurret)
		{
			Entry weapon = Catalog.Data.Weapons.First((Entry w) => w.Id == hero.TurretType);
			Deploy(player, weapon);
		}
		bool flag3 = false;
		enumerator = inventory.weaponInventory.weapons.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<EWeapon, WeaponBase> current2 = enumerator.Current;
			if (Catalog.WeaponsById.TryGetValue((int)current2.Key, out var value3) && value3.Id == "flowers")
			{
				flag3 = true;
			}
		}
		if ((flag3 || Effects.Value("flowerSeeds") > 0f) && num > 0.08f && Time.time >= nextFlower)
		{
			nextFlower = Time.time + 0.5f / Math.Max(1f, 1f + Effects.Value("flowerSeeds"));
			GameObject val3 = Object.Instantiate<GameObject>(DuckModel.Prefab("weapon_flowers"));
			val3.transform.position = player.feet.position;
			val3.SetActive(true);
			Flowers.Add(new Flower
			{
				Model = val3,
				Position = val3.transform.position,
				Born = Time.time
			});
		}
		Flower[] array3 = Flowers.ToArray();
		foreach (Flower flower in array3)
		{
			if (Time.time - flower.Born > 6f)
			{
				if ((Object)(object)flower.Model != (Object)null)
				{
					Object.Destroy((Object)(object)flower.Model);
				}
				Flowers.Remove(flower);
				continue;
			}
			Enemy[] array = Nearby(flower.Position, 2f, 8);
			foreach (Enemy enemy2 in array)
			{
				Deal(enemy2, Effects.Value("flowerPower") * Effects.Value("damage") * dt, "flower");
				if (Effects.Value("flowerRoots") > 0f)
				{
					SkillCompatibility.Slow(enemy2, Effects.Value("flowerRoots"), 3f);
				}
				if (Effects.Value("flowerPollen") > 0f)
				{
					Debuff(enemy2, (EDebuff)1, Effects.Value("flowerPollen"), 2f);
				}
			}
			if (Vector3.Distance(position, flower.Position) < 2f && Effects.Value("flowerHeal") > 0f)
			{
				Heal(Effects.Value("flowerHeal") * dt);
			}
		}
		Pool[] array4 = Pools.ToArray();
		foreach (Pool pool in array4)
		{
			if (Time.time >= pool.Until)
			{
				Pools.Remove(pool);
				continue;
			}
			Enemy[] array = Nearby(pool.Position, 3f);
			for (int num2 = 0; num2 < array.Length; num2++)
			{
				Deal(array[num2], pool.Damage * dt, "pool");
			}
		}
		SkillCompatibility.TickPickups(player, ref coinScan);
		if (Time.time < pulse)
		{
			return;
		}
		pulse = Time.time + 1f;
		Burst(position, Effects.Value("auraDamage"), 4f, "aura");
		Burst(position, Effects.Value("orbitDamage"), 3f, "orbit");
		if (Effects.Value("nova") > 0f)
		{
			Burst(position, Effects.Value("nova"), 6f, "nova");
		}
		if (Effects.Value("storm") > 0f)
		{
			Enemy[] array = Nearby(position, 20f, 3);
			for (int i = 0; i < array.Length; i++)
			{
				Deal(array[i], Effects.Value("storm"), "storm");
			}
		}
		if (Effects.Value("drones") > 0f)
		{
			Enemy[] array = Nearby(position, 15f, (int)Math.Clamp(Effects.Value("drones"), 0f, 3f));
			for (int i = 0; i < array.Length; i++)
			{
				Deal(array[i], Effects.Value("damage"), "drone");
			}
		}
		if (Effects.Value("interest") > 0f)
		{
			inventory.gold += inventory.gold * Math.Clamp(Effects.Value("interest"), 0f, 0.08f) / 60f;
		}
		if (Effects.Value("magnetPulse") > 0f)
		{
			inventory.statInventory.ChangeMovingStat("wf:magnet", new StatModifier
			{
				stat = (EStat)29,
				modification = Effects.Value("magnetPulse"),
				modifyType = (EStatModifyType)2
			});
		}
	}

	private static void OwnInvincibility(MyPlayer player)
	{
		if (!player.isInvincible)
		{
			player.isInvincible = true;
			ownsInvincibility = true;
		}
	}

	internal static void PollInput(MyPlayer player)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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)
		if (!Effects.Active)
		{
			return;
		}
		object obj;
		if (player == null)
		{
			obj = null;
		}
		else
		{
			PlayerMovement playerMovement = player.playerMovement;
			obj = ((playerMovement != null) ? playerMovement.rb : null);
		}
		if ((Object)obj == (Object)null)
		{
			return;
		}
		GameManager instance = GameManager.Instance;
		if (instance != null && instance.isPlaying && !(Time.timeScale <= 0f))
		{
			PlayerMovement playerMovement2 = player.playerMovement;
			if (Input.GetKeyDown((KeyCode)304))
			{
				TryDash(player);
			}
			if (!playerMovement2.grounded && Input.GetKeyDown((KeyCode)306))
			{
				slamming = true;
				Vector3 velocity = playerMovement2.rb.velocity;
				velocity.y = -24f;
				playerMovement2.rb.velocity = velocity;
			}
		}
	}

	internal static bool TryDash(MyPlayer player)
	{
		//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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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)
		if (!(Time.time < nextDash))
		{
			object obj;
			if (player == null)
			{
				obj = null;
			}
			else
			{
				PlayerMovement playerMovement = player.playerMovement;
				obj = ((playerMovement != null) ? playerMovement.rb : null);
			}
			if (!((Object)obj == (Object)null))
			{
				nextDash = Time.time + Math.Max(0.6f, Effects.Value("dashCooldown"));
				dashUntil = Time.time + 0.2f;
				Effects.DashedAt = Time.time;
				Vector3 val = player.playerMovement.GetWishDir();
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = player.playerMovement.orientation.forward;
				}
				val.y = 0f;
				player.playerMovement.rb.AddForce(((Vector3)(ref val)).normalized * 18f, (ForceMode)2);
				OwnInvincibility(player);
				return true;
			}
		}
		return false;
	}

	private static void Deploy(MyPlayer player, Entry weapon)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		nextTurret = Time.time + Math.Max(2f, Effects.Value("turretLife") * 0.35f);
		GameObject val = Object.Instantiate<GameObject>(DuckModel.Prefab("weapon_turret"));
		val.transform.position = player.feet.position + Vector3.right * 1.5f;
		val.SetActive(true);
		Turrets.Add(new Turret
		{
			Model = val,
			Position = val.transform.position,
			Weapon = weapon,
			Born = Time.time
		});
	}
}
internal static class Content
{
	internal const string Author = "Wildforge";

	internal const ECharacter Duck = (ECharacter)87001;

	internal const EWeapon Gun = (EWeapon)87001;

	internal const EItem Fang = (EItem)87001;

	internal const EItem Clover = (EItem)87002;

	internal const EItem Boots = (EItem)87003;

	internal static readonly Dictionary<string, string> Descriptions = new Dictionary<string, string>
	{
		["Count Duck"] = "A very normal duck. Blood Bank heals for 8% of actual weapon damage dealt.",
		["Breadcrumb Blaster"] = "Count Duck's gun. Fires a quick volley of extremely unfriendly breadcrumbs.",
		["Questionable Fang"] = "Heal for 2.5% of actual weapon damage dealt per stack.",
		["Clover Sandwich"] = "+14% luck per stack. Do not ask what is inside.",
		["Emergency Boots"] = "+12% movement speed per stack. For urgent waddling.",
		["Count Duck Default"] = "Count Duck's original Wildforge appearance."
	};

	internal static Texture2D Portrait;

	internal static bool IsOurs(UnlockableBase data)
	{
		if ((Object)(object)data != (Object)null)
		{
			return data.author == "Wildforge";
		}
		return false;
	}

	internal static bool IsItem(EItem item)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected I4, but got Unknown
		return Catalog.CardsById.ContainsKey((int)item);
	}

	internal static void Register(DataManager manager)
	{
		FullCatalog.Register(manager);
	}

	internal static void Setup(UnlockableBase data, string name)
	{
		((Object)data).name = name;
		data.author = "Wildforge";
		data.isEnabled = true;
		data.showInUnlocks = false;
		data.price = 0;
		data.sortingPriority = 1000;
		Object.DontDestroyOnLoad((Object)(object)data);
	}

	internal static ItemBase MakeItem(EItem id, ItemInventory inventory)
	{
		//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_0011: 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_0019: Expected I4, but got Unknown
		//IL_002b: Expected O, but got Unknown
		return (ItemBase)new ItemClover(inventory)
		{
			luckPerAmount = 0f,
			damageSource = "wildforge_item_" + (int)id
		};
	}

	internal static bool IsHero(ECharacter id)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected I4, but got Unknown
		return Catalog.HeroesById.ContainsKey((int)id);
	}

	internal static string Description(UnlockableBase data)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Expected I4, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected I4, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected I4, but got Unknown
		ItemData val = ((Il2CppObjectBase)data).TryCast<ItemData>();
		CharacterData val2 = ((Il2CppObjectBase)data).TryCast<CharacterData>();
		WeaponData val3 = ((Il2CppObjectBase)data).TryCast<WeaponData>();
		if ((Object)(object)val != (Object)null && Catalog.CardsById.TryGetValue((int)val.eItem, out var value))
		{
			return Catalog.Describe(value);
		}
		if ((Object)(object)val2 != (Object)null && Catalog.HeroesById.TryGetValue((int)val2.eCharacter, out var value2))
		{
			return Catalog.Describe(value2);
		}
		if ((Object)(object)val3 != (Object)null && Catalog.WeaponsById.TryGetValue((int)val3.eWeapon, out var value3))
		{
			return Catalog.Describe(value3);
		}
		return ((Object)data).name + " from Wildforge.";
	}

	internal static string InternalName(UnlockableBase data)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected I4, but got Unknown
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Expected I4, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected I4, but got Unknown
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Expected I4, but got Unknown
		ItemData val = ((Il2CppObjectBase)data).TryCast<ItemData>();
		if ((Object)(object)val != (Object)null)
		{
			return "wildforge_card_" + (int)val.eItem;
		}
		CharacterData val2 = ((Il2CppObjectBase)data).TryCast<CharacterData>();
		if ((Object)(object)val2 != (Object)null)
		{
			return "wildforge_hero_" + (int)val2.eCharacter;
		}
		WeaponData val3 = ((Il2CppObjectBase)data).TryCast<WeaponData>();
		if ((Object)(object)val3 != (Object)null)
		{
			return "wildforge_weapon_" + (int)val3.eWeapon;
		}
		SkinData val4 = ((Il2CppObjectBase)data).TryCast<SkinData>();
		if ((Object)(object)val4 != (Object)null)
		{
			return "wildforge_skin_" + (int)val4.character;
		}
		return "wildforge_" + ((Object)data).name.ToLowerInvariant().Replace(' ', '_');
	}
}
[HarmonyPatch(typeof(DataManager), "Load")]
internal static class RegisterContent
{
	private static void Postfix(DataManager __instance)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		try
		{
			Content.Register(__instance);
		}
		catch (Exception ex)
		{
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Wildforge registration failed: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
			}
			logger.LogError(val);
		}
	}
}
[HarmonyPatch(typeof(UnlockableBase), "GetName")]
internal static class ContentName
{
	private static void Postfix(UnlockableBase __instance, ref string __result)
	{
		if (Content.IsOurs(__instance))
		{
			__result = ((Object)__instance).name;
		}
	}
}
[HarmonyPatch(typeof(UnlockableBase), "GetDescription")]
internal static class ContentDescription
{
	private static void Postfix(UnlockableBase __instance, ref string __result)
	{
		if (Content.IsOurs(__instance))
		{
			__result = Content.Description(__instance);
		}
	}
}
[HarmonyPatch(typeof(ItemData), "GetName")]
internal static class ItemName
{
	private static void Postfix(ItemData __instance, ref string __result)
	{
		if (Content.IsOurs((UnlockableBase)(object)__instance))
		{
			__result = ((Object)__instance).name;
		}
	}
}
[HarmonyPatch]
internal static class ItemDescription
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		yield return AccessTools.Method(typeof(ItemData), "GetDescription", (Type[])null, (Type[])null);
	}

	private static void Postfix(ItemData __instance, ref string __result)
	{
		if (Content.IsOurs((UnlockableBase)(object)__instance))
		{
			__result = Content.Description((UnlockableBase)(object)__instance);
		}
	}
}
[HarmonyPatch(typeof(PassiveData), "GetName")]
internal static class PassiveName
{
	private static void Postfix(PassiveData __instance, ref string __result)
	{
		if (FullCatalog.Passives.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out var value))
		{
			__result = value.Perk;
		}
	}
}
[HarmonyPatch(typeof(PassiveData), "GetDescription")]
internal static class PassiveDescription
{
	private static void Postfix(PassiveData __instance, ref string __result)
	{
		if (FullCatalog.Passives.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out var value))
		{
			__result = Catalog.Describe(value);
		}
	}
}
[HarmonyPatch]
internal static class AvailableContent
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		string[] array = new string[3] { "IsPurchased", "IsAvailable", "IsActivated" };
		foreach (string text in array)
		{
			yield return AccessTools.Method(typeof(MyAchievements), text, (Type[])null, (Type[])null);
		}
	}

	private static bool Prefix(UnlockableBase unlockable, ref bool __result)
	{
		if (!Content.IsOurs(unlockable))
		{
			return true;
		}
		__result = true;
		return false;
	}
}
[HarmonyPatch(typeof(CharacterData), "IsBlackedOutInCharacterSelectionScreen")]
internal static class DuckVisible
{
	private static bool Prefix(CharacterData __instance, ref bool __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		if (!Content.IsHero(__instance.eCharacter))
		{
			return true;
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(CharacterData), "GetDisplayRank")]
internal static class DuckRank
{
	private static bool Prefix(CharacterData __instance, ref int __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		if (!Content.IsHero(__instance.eCharacter))
		{
			return true;
		}
		__result = 0;
		return false;
	}
}
[HarmonyPatch(typeof(DataManager), "GetSkin")]
internal static class DuckSkin
{
	private static bool Prefix(DataManager __instance, ECharacter character, ref SkinData __result)
	{
		//IL_0000: 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_001f: Unknown result type (might be due to invalid IL or missing references)
		if (!Content.IsHero(character) || !__instance.skinData.ContainsKey(character))
		{
			return true;
		}
		__result = __instance.skinData[character][0];
		return false;
	}
}
[HarmonyPatch(typeof(ItemFactory), "CreateItem")]
internal static class CustomItemFactory
{
	private static bool Prefix(EItem eItem, ItemInventory inventory, ref ItemBase __result)
	{
		//IL_0000: 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)
		if (!Content.IsItem(eItem))
		{
			return true;
		}
		__result = Content.MakeItem(eItem, inventory);
		return false;
	}
}
internal static class DuckModel
{
	private sealed class HeroView
	{
		internal PlayerRenderer Renderer;

		internal PlayerInventory Inventory;

		internal GameObject Model;

		internal OrbHealth Orbs;

		internal Transform[] Limbs;
	}

	private static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

	private static readonly Dictionary<IntPtr, HeroView> Heroes = new Dictionary<IntPtr, HeroView>();

	internal static bool HasPartialHealthOrb => Heroes.Values.Any((HeroView v) => v.Orbs.Count > 0 && v.Orbs.FillPercent > 0 && v.Orbs.FillPercent < 100);

	internal static GameObject Prefab(string asset)
	{
		if (!Prefabs.TryGetValue(asset, out var value))
		{
			value = (Prefabs[asset] = Load(asset));
		}
		return value;
	}

	internal static void Prepare()
	{
		Prefab("count_duck");
	}

	internal static void Tick()
	{
		//IL_00d1: 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_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: 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)
		KeyValuePair<IntPtr, HeroView>[] array = Heroes.ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			KeyValuePair<IntPtr, HeroView> keyValuePair = array[i];
			HeroView value = keyValuePair.Value;
			if ((Object)(object)value.Renderer == (Object)null || (Object)(object)value.Model == (Object)null)
			{
				Heroes.Remove(keyValuePair.Key);
				continue;
			}
			((Renderer)value.Renderer.renderer).forceRenderingOff = true;
			float num = Mathf.Sin(Time.time * (float)(value.Renderer.moving ? 10 : 2)) * (float)(value.Renderer.moving ? 24 : 2);
			for (int j = 0; j < value.Limbs.Length; j++)
			{
				if ((Object)(object)value.Limbs[j] != (Object)null)
				{
					value.Limbs[j].localRotation = Quaternion.Euler(num * (float)((j % 2 == 0) ? 1 : (-1)), 0f, 0f);
				}
			}
			MyPlayer instance = MyPlayer.Instance;
			PlayerInventory val = ((instance != null) ? instance.inventory : null);
			ECharacter? obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				CharacterData characterData = val.characterData;
				obj = ((characterData != null) ? new ECharacter?(characterData.eCharacter) : ((ECharacter?)null));
			}
			object obj2;
			if (obj != (ECharacter?)value.Renderer.characterData.eCharacter)
			{
				PlayerInventory inventory = value.Inventory;
				obj2 = ((inventory != null) ? inventory.playerHealth : null);
			}
			else
			{
				obj2 = val.playerHealth;
			}
			PlayerHealth val2 = (PlayerHealth)obj2;
			value.Orbs.Update((val2 == null) ? 1f : ((float)val2.hp / (float)Math.Max(1, val2.maxHp)));
		}
	}

	internal static void Attach(PlayerRenderer renderer, PlayerInventory inventory)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected I4, but got Unknown
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		if (Heroes.Remove(((Il2CppObjectBase)renderer).Pointer, out var value))
		{
			value.Orbs.Dispose();
			if ((Object)(object)value.Model != (Object)null)
			{
				Object.Destroy((Object)(object)value.Model);
			}
		}
		if (!Catalog.HeroesById.TryGetValue((int)renderer.characterData.eCharacter, out var value2))
		{
			if ((Object)(object)renderer.renderer != (Object)null)
			{
				((Renderer)renderer.renderer).forceRenderingOff = false;
			}
			return;
		}
		GameObject val = Object.Instantiate<GameObject>(Prefab(value2.Asset), renderer.rendererObject.transform);
		((Object)val).name = "Wildforge_" + value2.Id;
		val.transform.localPosition = Vector3.zero;
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one;
		val.SetActive(true);
		((Renderer)renderer.renderer).forceRenderingOff = true;
		Transform[] limbs = ((IEnumerable<Transform>)val.GetComponentsInChildren<Transform>(true)).Where((Transform t) => ((Object)t).name.StartsWith("Leg") || ((Object)t).name.StartsWith("Arm")).ToArray();
		Heroes[((Il2CppObjectBase)renderer).Pointer] = new HeroView
		{
			Renderer = renderer,
			Inventory = inventory,
			Model = val,
			Orbs = new OrbHealth(val),
			Limbs = limbs
		};
		Plugin.Logger.LogInfo((object)("Wildforge hero model attached: " + value2.Name));
	}

	private static GameObject Load(string asset)
	{
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Expected O, but got Unknown
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Expected O, but got Unknown
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		byte[] bytes = File.ReadAllBytes(Path.Combine(Plugin.AssetDirectory, asset + ".glb"));
		if (BitConverter.ToUInt32(bytes, 0) != 1179937895 || BitConverter.ToUInt32(bytes, 4) != 2)
		{
			throw new InvalidDataException("Invalid Wildforge GLB: " + asset);
		}
		int num = BitConverter.ToInt32(bytes, 12);
		int binaryOffset;
		JsonElement views;
		JsonElement accessors;
		using (JsonDocument jsonDocument = JsonDocument.Parse(bytes.AsMemory(20, num)))
		{
			JsonElement rootElement = jsonDocument.RootElement;
			binaryOffset = 28 + num;
			views = rootElement.GetProperty("bufferViews");
			accessors = rootElement.GetProperty("accessors");
			Texture2D paper = TextureLoader.Load(Path.Combine(Plugin.AssetDirectory, "paper.png"));
			Shader shader = Shader.Find("Standard") ?? Shader.Find("Unlit/Texture");
			if ((Object)(object)shader == (Object)null)
			{
				throw new InvalidOperationException("No compatible model shader found");
			}
			Material[] materials = rootElement.GetProperty("materials").EnumerateArray().Select(delegate(JsonElement m)
			{
				//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_0066: 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_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Expected O, but got Unknown
				JsonElement property2 = m.GetProperty("pbrMetallicRoughness").GetProperty("baseColorFactor");
				Material val3 = new Material(shader);
				Color val4 = new Color(property2[0].GetSingle(), property2[1].GetSingle(), property2[2].GetSingle(), property2[3].GetSingle());
				val3.color = ((Color)(ref val4)).gamma;
				val3.mainTexture = (Texture)(object)paper;
				Material val5 = val3;
				if (val5.HasProperty("_Glossiness"))
				{
					val5.SetFloat("_Glossiness", 0f);
				}
				return val5;
			})
				.ToArray();
			(Mesh, Material)[] array = rootElement.GetProperty("meshes").EnumerateArray().Select(delegate(JsonElement m)
			{
				//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_00e3: 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_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Expected O, but got Unknown
				JsonElement jsonElement2 = m.GetProperty("primitives")[0];
				JsonElement property2 = jsonElement2.GetProperty("attributes");
				float[] array3 = ReadFloat(property2.GetProperty("POSITION").GetInt32(), 3);
				float[] array4 = ReadFloat(property2.GetProperty("NORMAL").GetInt32(), 3);
				float[] array5 = ReadFloat(property2.GetProperty("TEXCOORD_0").GetInt32(), 2);
				Vector3[] array6 = (Vector3[])(object)new Vector3[array3.Length / 3];
				Vector3[] array7 = (Vector3[])(object)new Vector3[array6.Length];
				Vector2[] array8 = (Vector2[])(object)new Vector2[array6.Length];
				for (int i = 0; i < array6.Length; i++)
				{
					array6[i] = new Vector3(array3[i * 3], array3[i * 3 + 1], 0f - array3[i * 3 + 2]);
					array7[i] = new Vector3(array4[i * 3], array4[i * 3 + 1], 0f - array4[i * 3 + 2]);
					array8[i] = new Vector2(array5[i * 2], 1f - array5[i * 2 + 1]);
				}
				Mesh val3 = new Mesh
				{
					name = m.GetProperty("name").GetString()
				};
				DuckModel.SetChannel<Vector3>(val3, (VertexAttribute)0, 3, array6);
				DuckModel.SetChannel<Vector3>(val3, (VertexAttribute)1, 3, array7);
				DuckModel.SetChannel<Vector2>(val3, (VertexAttribute)4, 2, array8);
				int[] array9 = ReadIndices(jsonElement2.GetProperty("indices").GetInt32());
				GCHandle gCHandle = GCHandle.Alloc(array9, GCHandleType.Pinned);
				try
				{
					Mesh.SetIndicesNativeArrayImpl_Injected(((Object)val3).m_CachedPtr, 0, (MeshTopology)0, (IndexFormat)1, gCHandle.AddrOfPinnedObject(), 0, array9.Length, true, 0);
				}
				finally
				{
					gCHandle.Free();
				}
				val3.RecalculateBounds();
				return (mesh: val3, material: materials[jsonElement2.GetProperty("material").GetInt32()]);
			})
				.ToArray();
			GameObject val = new GameObject("WildforgePrefab_" + asset);
			JsonElement property = rootElement.GetProperty("nodes");
			GameObject[] array2 = ((IEnumerable<JsonElement>)property.EnumerateArray()).Select((Func<JsonElement, GameObject>)((JsonElement n) => new GameObject(n.GetProperty("name").GetString()))).ToArray();
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				JsonElement jsonElement = property[num2];
				array2[num2].transform.SetParent(val.transform, false);
				if (jsonElement.TryGetProperty("translation", out var value))
				{
					array2[num2].transform.localPosition = new Vector3(value[0].GetSingle(), value[1].GetSingle(), 0f - value[2].GetSingle());
				}
				if (jsonElement.TryGetProperty("rotation", out var value2))
				{
					array2[num2].transform.localRotation = new Quaternion(0f - value2[0].GetSingle(), 0f - value2[1].GetSingle(), value2[2].GetSingle(), value2[3].GetSingle());
				}
				if (jsonElement.TryGetProperty("scale", out var value3))
				{
					array2[num2].transform.localScale = new Vector3(value3[0].GetSingle(), value3[1].GetSingle(), value3[2].GetSingle());
				}
				if (jsonElement.TryGetProperty("mesh", out var value4))
				{
					(Mesh, Material) tuple = array[value4.GetInt32()];
					array2[num2].AddComponent<MeshFilter>().sharedMesh = tuple.Item1;
					((Renderer)array2[num2].AddComponent<MeshRenderer>()).sharedMaterial = tuple.Item2;
				}
			}
			for (int num3 = 0; num3 < array2.Length; num3++)
			{
				if (!property[num3].TryGetProperty("children", out var value5))
				{
					continue;
				}
				foreach (JsonElement item in value5.EnumerateArray())
				{
					array2[item.GetInt32()].transform.SetParent(array2[num3].transform, false);
				}
			}
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(37, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Loaded Wildforge model ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(asset);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(array.Length);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" mesh parts.");
			}
			logger.LogInfo(val2);
			return val;
		}
		float[] ReadFloat(int id, int width)
		{
			JsonElement element = accessors[id];
			if (element.GetProperty("componentType").GetInt32() != 5126)
			{
				throw new InvalidDataException("Only float mesh attributes supported");
			}
			JsonElement element2 = views[element.GetProperty("bufferView").GetInt32()];
			int num4 = binaryOffset + GetInt(element2, "byteOffset") + GetInt(element, "byteOffset");
			int @int = element.GetProperty("count").GetInt32();
			JsonElement value6;
			int num5 = (element2.TryGetProperty("byteStride", out value6) ? value6.GetInt32() : (width * 4));
			float[] array3 = new float[@int * width];
			for (int i = 0; i < @int; i++)
			{
				for (int j = 0; j < width; j++)
				{
					array3[i * width + j] = BitConverter.ToSingle(bytes, num4 + i * num5 + j * 4);
				}
			}
			return array3;
		}
		int[] ReadIndices(int id)
		{
			JsonElement element = accessors[id];
			JsonElement element2 = views[element.GetProperty("bufferView").GetInt32()];
			int num4 = binaryOffset + GetInt(element2, "byteOffset") + GetInt(element, "byteOffset");
			int @int = element.GetProperty("count").GetInt32();
			int num5 = element.GetProperty("componentType").GetInt32() switch
			{
				5121 => 1, 
				5123 => 2, 
				5125 => 4, 
				_ => throw new InvalidDataException("Invalid indices"), 
			};
			int[] array3 = new int[@int];
			for (int i = 0; i < @int; i++)
			{
				int[] array4 = array3;
				int num6 = i;
				array4[num6] = num5 switch
				{
					1 => bytes[num4 + i], 
					2 => BitConverter.ToUInt16(bytes, num4 + i * 2), 
					_ => checked((int)BitConverter.ToUInt32(bytes, num4 + i * 4)), 
				};
			}
			for (int j = 0; j < @int; j += 3)
			{
				ref int reference = ref array3[j + 1];
				ref int reference2 = ref array3[j + 2];
				int num7 = array3[j + 2];
				int num6 = array3[j + 1];
				reference = num7;
				reference2 = num6;
			}
			return array3;
		}
	}

	private static int GetInt(JsonElement element, string key)
	{
		if (!element.TryGetProperty(key, out var value))
		{
			return 0;
		}
		return value.GetInt32();
	}

	internal static void SetChannel<T>(Mesh mesh, VertexAttribute channel, int width, T[] values) where T : struct
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		GCHandle gCHandle = GCHandle.Alloc(values, GCHandleType.Pinned);
		try
		{
			Mesh.SetNativeArrayForChannelImpl_Injected(((Object)mesh).m_CachedPtr, channel, (VertexAttributeFormat)0, width, gCHandle.AddrOfPinnedObject(), values.Length, 0, values.Length, (MeshUpdateFlags)0);
		}
		finally
		{
			gCHandle.Free();
		}
	}
}
[HarmonyPatch(typeof(PlayerRenderer), "SetCharacter")]
internal static class DuckRenderer
{
	private static void Prefix(CharacterData characterData)
	{
		//IL_0001: 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)
		if (Content.IsHero(characterData.eCharacter))
		{
			SaveManager.Instance.config.preferences.characterSkins.TryAdd(characterData.eCharacter, 0);
		}
	}

	private static void Postfix(PlayerRenderer __instance, PlayerInventory inventory)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		try
		{
			DuckModel.Attach(__instance, inventory);
		}
		catch (Exception ex)
		{
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Wildforge hero model failed: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
			}
			logger.LogError(val);
		}
	}
}
[HarmonyPatch(typeof(MyPlayer), "StartPlayer")]
internal static class DuckStart
{
	internal static void Initialize(MyPlayer player, ECharacter character = (ECharacter)87001)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected I4, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_007d: Expected O, but got Unknown
		//IL_0082: Expected O, but got Unknown
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		if (!Catalog.HeroesById.TryGetValue((int)character, out var hero))
		{
			return;
		}
		PlayerInventory val = player.inventory;
		int num;
		if (val == null)
		{
			num = 1;
		}
		else
		{
			CharacterData characterData = val.characterData;
			num = ((((characterData != null) ? new ECharacter?(characterData.eCharacter) : ((ECharacter?)null)) != (ECharacter?)character) ? 1 : 0);
			if (num == 0)
			{
				goto IL_0082;
			}
		}
		PlayerInventory val2 = new PlayerInventory(DataManager.Instance.characterData[character], false);
		val = val2;
		player.inventory = val2;
		goto IL_0082;
		IL_0082:
		player.character = character;
		EWeapon val3 = (EWeapon)Catalog.Data.Weapons.First((Entry w) => w.Id == hero.Weapon).RuntimeId;
		if (!val.weaponInventory.weapons.ContainsKey(val3))
		{
			val.weaponInventory.AddWeapon(DataManager.Instance.weapons[val3], new List<StatModifier>());
		}
		if (num != 0)
		{
			MyPlayer.A_PlayerInventoryInitialized?.Invoke(val);
		}
		Effects.Tick(force: true);
		Plugin.Logger.LogInfo((object)("Wildforge hero initialized: " + hero.Name));
	}

	private static void Postfix(MyPlayer __instance, ECharacter character)
	{
		//IL_0000: 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 (Content.IsHero(character))
		{
			Initialize(__instance, character);
		}
	}
}
internal static class Effects
{
	internal static readonly Dictionary<string, EStat> NativeStats = new Dictionary<string, EStat>
	{
		["damage"] = (EStat)12,
		["rate"] = (EStat)15,
		["speed"] = (EStat)25,
		["maxHp"] = (EStat)0,
		["armor"] = (EStat)4,
		["regen"] = (EStat)1,
		["shield"] = (EStat)2,
		["thorns"] = (EStat)3,
		["dodge"] = (EStat)5,
		["crit"] = (EStat)18,
		["critPower"] = (EStat)19,
		["size"] = (EStat)9,
		["range"] = (EStat)10,
		["projectileSpeed"] = (EStat)11,
		["knockback"] = (EStat)24,
		["multishot"] = (EStat)16,
		["ricochet"] = (EStat)45,
		["xpGain"] = (EStat)32,
		["goldGain"] = (EStat)31,
		["chestBonus"] = (EStat)33,
		["pickup"] = (EStat)29,
		["luck"] = (EStat)30,
		["jumpHeight"] = (EStat)26,
		["airJumps"] = (EStat)46,
		["fallGuard"] = (EStat)27,
		["slamPower"] = (EStat)28,
		["potionDuration"] = (EStat)14,
		["potionPower"] = (EStat)40,
		["potionChance"] = (EStat)41
	};

	private static readonly HashSet<string> Ratios = new HashSet<string>
	{
		"damage", "rate", "speed", "maxHp", "critPower", "size", "range", "projectileSpeed", "xpGain", "goldGain",
		"pickup", "jumpHeight", "slamPower", "potionDuration", "potionPower", "coinRadius"
	};

	private static readonly Dictionary<string, float> Caps = new Dictionary<string, float>
	{
		["airJumps"] = 8f,
		["keyPower"] = 0.75f,
		["fallGuard"] = 0.95f,
		["jumpHeight"] = 5f,
		["slamRadius"] = 4f,
		["bounceJump"] = 2f,
		["flowerSeeds"] = 2f,
		["flowerRoots"] = 0.7f,
		["rate"] = 18f,
		["speed"] = 18f,
		["maxHp"] = 5000f,
		["damage"] = 3000f,
		["dodge"] = 0.65f,
		["lifesteal"] = 0.4f,
		["crit"] = 0.85f,
		["freeze"] = 0.65f,
		["blind"] = 0.65f,
		["discount"] = 0.6f,
		["multishot"] = 7f,
		["chain"] = 8f,
		["pierce"] = 12f,
		["turretCount"] = 1f,
		["drones"] = 3f,
		["interest"] = 0.08f,
		["ghost"] = 2f,
		["pickup"] = 20f,
		["coinRadius"] = 22f,
		["regen"] = 40f,
		["revive"] = 4f,
		["discBounces"] = 8f,
		["boomerangPierce"] = 12f,
		["harpoonPull"] = 3f,
		["gravitySize"] = 4f,
		["hornStun"] = 3f,
		["bubbleTime"] = 4f,
		["meteorCount"] = 5f,
		["bombSize"] = 4f,
		["airDamage"] = 3f,
		["landingHeal"] = 50f,
		["slamHeal"] = 50f,
		["airControl"] = 0.5f,
		["fallThreshold"] = 20f,
		["potionDuration"] = 4f,
		["potionPower"] = 3f,
		["potionChance"] = 0.6f,
		["jumpShield"] = 100f,
		["jumpBlast"] = 200f,
		["slamFire"] = 100f,
		["slamPoison"] = 100f,
		["coinHeal"] = 20f,
		["chestHeal"] = 200f,
		["size"] = 2.5f,
		["knockback"] = 3f,
		["slow"] = 0.7f,
		["banana"] = 0.6f
	};

	internal static readonly Dictionary<string, float> Values = new Dictionary<string, float>();

	private static readonly Dictionary<string, float> Applied = new Dictionary<string, float>();

	private static readonly Dictionary<string, (float Amount, string Mode)> Conditional = new Dictionary<string, (float, string)>();

	internal static bool Active;

	internal static Func<string, bool> ConditionOverride;

	private static IntPtr inventoryPointer;

	private static float nextTick;

	internal static float KilledAt = -100f;

	internal static float HurtAt = -100f;

	internal static float SlamAt = -100f;

	internal static float DashedAt = -100f;

	internal static bool ExtraDamage;

	internal static float Value(string key)
	{
		return Values.GetValueOrDefault(key, Catalog.Data?.Stats.GetValueOrDefault(key, 0f) ?? 0f);
	}

	internal static float Bonus(string key)
	{
		return Value(key) - (Catalog.Data?.Stats.GetValueOrDefault(key, 0f) ?? 0f);
	}

	internal static void Tick(bool force = false)
	{
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Expected I4, but got Unknown
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Expected I4, but got Unknown
		//IL_037c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Expected O, but got Unknown
		MyPlayer instance = MyPlayer.Instance;
		PlayerInventory val = ((instance != null) ? instance.inventory : null);
		if (Catalog.Data == null || ((val != null) ? val.statInventory : null) == null || (!force && Time.time < nextTick))
		{
			return;
		}
		nextTick = Time.time + 0.15f;
		if (inventoryPointer != ((Il2CppObjectBase)val).Pointer)
		{
			inventoryPointer = ((Il2CppObjectBase)val).Pointer;
			Applied.Clear();
			CombatEffects.Reset();
		}
		Values.Clear();
		Conditional.Clear();
		foreach (KeyValuePair<string, float> stat in Catalog.Data.Stats)
		{
			if (!stat.Key.StartsWith("augment-"))
			{
				Values[stat.Key] = stat.Value;
			}
		}
		bool flag = false;
		if (Catalog.HeroesById.TryGetValue((int)val.characterData.eCharacter, out var value))
		{
			Apply(value.Effects, 1);
			flag = true;
		}
		Enumerator<EItem, ItemBase> enumerator2 = val.itemInventory.items.GetEnumerator();
		while (enumerator2.MoveNext())
		{
			KeyValuePair<EItem, ItemBase> current2 = enumerator2.Current;
			if (Catalog.CardsById.TryGetValue((int)current2.Key, out var value2))
			{
				Apply(value2.Effects, current2.Value.amount);
				flag = true;
			}
		}
		foreach (KeyValuePair<string, (float, string)> item in Conditional)
		{
			Values[item.Key] = ((item.Value.Item2 == "multiply") ? (Values.GetValueOrDefault(item.Key) * (1f + item.Value.Item1)) : (Values.GetValueOrDefault(item.Key) + item.Value.Item1));
		}
		Active = flag;
		foreach (KeyValuePair<string, float> cap in Caps)
		{
			if (Values.ContainsKey(cap.Key))
			{
				Values[cap.Key] = Math.Min(Values[cap.Key], cap.Value);
			}
		}
		bool flag2 = false;
		foreach (KeyValuePair<string, EStat> nativeStat in NativeStats)
		{
			string text = "wf:" + nativeStat.Key;
			float valueOrDefault = Catalog.Data.Stats.GetValueOrDefault(nativeStat.Key, 0f);
			float num = ((Ratios.Contains(nativeStat.Key) && valueOrDefault != 0f) ? (Value(nativeStat.Key) / valueOrDefault - 1f) : (Value(nativeStat.Key) - valueOrDefault));
			if (nativeStat.Key == "regen")
			{
				num *= 60f;
			}
			if (!flag)
			{
				num = 0f;
			}
			if (!Applied.TryGetValue(text, out var value3) || !(Math.Abs(value3 - num) < 1E-05f))
			{
				if (Math.Abs(num) < 1E-05f)
				{
					val.statInventory.RemoveMovingStat(text);
				}
				else
				{
					val.statInventory.ChangeMovingStat(text, new StatModifier
					{
						stat = nativeStat.Value,
						modifyType = (EStatModifyType)(Ratios.Contains(nativeStat.Key) ? 1 : 2),
						modification = (Ratios.Contains(nativeStat.Key) ? (1f + num) : num)
					});
				}
				Applied[text] = num;
				flag2 = true;
			}
		}
		flag2 |= SetSpecial(val, "discount", (EStat)34, 0f - Math.Clamp(Value("discount"), 0f, 0.6f), (EStatModifyType)1);
		bool num2 = flag2;
		PlayerMovement playerMovement = instance.playerMovement;
		if (num2 | SetSpecial(val, "airControl", (EStat)25, (playerMovement != null && !playerMovement.grounded) ? Bonus("airControl") : 0f, (EStatModifyType)1))
		{
			val.playerStats.ForceUpdateStats();
			val.statInventory.Tick();
			val.playerStats.TryPopStatUpdatesQueue();
		}
		if (flag)
		{
			CombatEffects.Tick(instance, 0.15f);
		}
	}

	private static bool SetSpecial(PlayerInventory inv, string name, EStat stat, float value, EStatModifyType mode)
	{
		//IL_0049: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Invalid comparison between Unknown and I4
		//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_0077: Expected O, but got Unknown
		string text = "wf:" + name;
		if (Applied.TryGetValue(text, out var value2) && Math.Abs(value2 - value) < 1E-05f)
		{
			return false;
		}
		if (value == 0f)
		{
			inv.statInventory.RemoveMovingStat(text);
		}
		else
		{
			inv.statInventory.ChangeMovingStat(text, new StatModifier
			{
				stat = stat,
				modification = (((int)mode == 1) ? (1f + value) : value),
				modifyType = mode
			});
		}
		Applied[text] = value;
		return true;
	}

	private static void Apply(IEnumerable<EffectDef> effects, int count)
	{
		foreach (EffectDef effect in effects)
		{
			string key = effect.Key;
			string mode = effect.Mode;
			if (Catalog.Data.Augments.TryGetValue(key, out var value))
			{
				if (Condition(value.Condition))
				{
					(float, string) valueOrDefault = Conditional.GetValueOrDefault(value.Stat);
					Conditional[value.Stat] = (valueOrDefault.Item1 + effect.Amount * (float)count, value.Mode);
				}
			}
			else
			{
				float valueOrDefault2 = Values.GetValueOrDefault(key, 0f);
				Values[key] = ((mode == "multiply") ? (valueOrDefault2 * MathF.Pow(1f + effect.Amount, count)) : (valueOrDefault2 + effect.Amount * (float)count));
			}
		}
	}

	internal static bool Condition(string name)
	{
		//IL_0067: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
		if (ConditionOverride != null)
		{
			return ConditionOverride(name);
		}
		MyPlayer instance = MyPlayer.Instance;
		if (((instance != null) ? instance.inventory : null) == null)
		{
			return false;
		}
		PlayerMovement playerMovement = instance.playerMovement;
		PlayerHealth playerHealth = instance.inventory.playerHealth;
		Vector3? obj;
		if (playerMovement == null)
		{
			obj = null;
		}
		else
		{
			Rigidbody rb = playerMovement.rb;
			obj = ((rb != null) ? new Vector3?(rb.velocity) : ((Vector3?)null));
		}
		Vector3 val = (Vector3)(((??)obj) ?? Vector3.zero);
		Vector2 val2 = new Vector2(val.x, val.z);
		float magnitude = ((Vector2)(ref val2)).magnitude;
		float num = (float)playerHealth.hp / (float)Math.Max(1, playerHealth.maxHp);
		Enemy[] source = CombatEffects.Enemies();
		Vector3 position = ((Component)instance).transform.position;
		return name switch
		{
			"air" => playerMovement != null && !playerMovement.grounded, 
			"ground" => playerMovement != null && playerMovement.grounded, 
			"moving" => magnitude > 1f, 
			"still" => magnitude < 0.5f, 
			"low" => num < 0.4f, 
			"healthy" => num > 0.8f, 
			"shield" => playerHealth.shield > 0f, 
			"bare" => playerHealth.shield <= 0f, 
			"dash" => Time.time - DashedAt < 3f || (playerMovement != null && playerMovement.isDashing), 
			"slam" => Time.time - SlamAt < 4f, 
			"kill" => Time.time - KilledAt < 3f, 
			"hurt" => Time.time - HurtAt < 4f, 
			"boss" => source.Any(delegate(Enemy e)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (CombatEffects.IsBoss(e))
				{
					Vector3 val3 = ((Component)e).transform.position - position;
					return ((Vector3)(ref val3)).sqrMagnitude < 625f;
				}
				return false;
			}), 
			"alone" => !source.Any(delegate(Enemy e)
			{
				//IL_0006: 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_0011: 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)
				Vector3 val3 = ((Component)e).transform.position - position;
				return ((Vector3)(ref val3)).sqrMagnitude < 64f;
			}), 
			"crowd" => source.Count(delegate(Enemy e)
			{
				//IL_0006: 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_0011: 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)
				Vector3 val3 = ((Component)e).transform.position - position;
				return ((Vector3)(ref val3)).sqrMagnitude < 144f;
			}) >= 4, 
			"flower" => CombatEffects.NearFlower(position), 
			"turret" => CombatEffects.NearTurret(position), 
			"rich" => instance.inventory.gold >= 50f, 
			_ => false, 
		};
	}
}
[HarmonyPatch(typeof(UpgradePicker), "ShuffleUpgrades")]
internal static class WildforgeCardsInLevelups
{
	private static void Postfix(UpgradePicker __instance)
	{
		if (Catalog.Data == null || __instance.buttons == null)
		{
			return;
		}
		HashSet<int> hashSet = new HashSet<int>();
		for (int i = 1; i < ((Il2CppArrayBase<UpgradeButton>)(object)__instance.buttons).Length; i += 2)
		{
			MyPlayer instance = MyPlayer.Instance;
			float? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerInventory inventory = instance.inventory;
				obj = ((inventory != null) ? new float?(inventory.playerStats.GetStat((EStat)30)) : ((float?)null));
			}
			float? num = obj;
			float valueOrDefault = num.GetValueOrDefault();
			float num2 = Random.value + Math.Min(valueOrDefault, 0.75f) * 0.18f;
			int rarity = ((num2 > 0.987f) ? 3 : ((num2 > 0.91f) ? 2 : ((num2 > 0.66f) ? 1 : 0)));
			Entry[] array = Catalog.Data.Cards.Where((Entry c) => c.Kind == "skill" && c.Rarity == rarity).ToArray();
			if (array.Length == 0)
			{
				array = Catalog.Data.Cards.Where((Entry c) => c.Kind == "skill").ToArray();
			}
			Entry entry = array[Random.Range(0, array.Length)];
			if (hashSet.Add(entry.RuntimeId))
			{
				((Il2CppArrayBase<UpgradeButton>)(object)__instance.buttons)[i].SetItem(DataManager.Instance.itemData[(EItem)entry.RuntimeId]);
			}
		}
	}
}
[HarmonyPatch(typeof(UpgradeButton), "SetItem")]
internal static class WildforgeCardPresentation
{
	private static void Postfix(UpgradeButton __instance, ItemData itemData)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected I4, but got Unknown
		if (Catalog.CardsById.TryGetValue((int)itemData.eItem, out var value))
		{
			((TMP_Text)__instance.t_name).text = value.Title ?? value.Name;
			((TMP_Text)__instance.t_description).text = Catalog.Describe(value);
			__instance.icon.texture = (Texture)(object)FullCatalog.Icon(value.Portrait);
		}
	}
}
internal static class EnemyModels
{
	private sealed class View
	{
		internal Enemy Enemy;

		internal GameObject Model;

		internal OrbHealth Orbs;

		internal Entry Entry;
	}

	private static readonly Dictionary<IntPtr, View> Views = new Dictionary<IntPtr, View>();

	internal static int AttachedCount => Views.Count;

	internal static bool HasPartialHealthOrb => Views.Values.Any((View v) => v.Orbs.Count > 0 && v.Orbs.FillPercent > 0 && v.Orbs.FillPercent < 100);

	internal static void Attach(Enemy enemy)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected I4, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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)
		if (Views.Remove(((Il2CppObjectBase)enemy).Pointer, out var value))
		{
			value.Orbs.Dispose();
			if ((Object)(object)value.Model != (Object)null)
			{
				Object.Destroy((Object)(object)value.Model);
			}
		}
		if (!Catalog.EnemiesById.TryGetValue((int)enemy.enemyData.enemyName, out var value2))
		{
			if ((Object)(object)enemy.renderer != (Object)null)
			{
				enemy.renderer.forceRenderingOff = false;
			}
			return;
		}
		GameObject val = Object.Instantiate<GameObject>(DuckModel.Prefab(value2.Asset), ((Component)enemy).transform);
		val.transform.localPosition = Vector3.zero;
		val.transform.localRotation = Quaternion.identity;
		if (value2.Boss)
		{
			val.transform.localScale = Vector3.one * (value2.Height / 4.1f);
		}
		((Object)val).name = "WildforgeEnemy_" + value2.Id;
		val.SetActive(true);
		enemy.renderer.forceRenderingOff = true;
		Views[((Il2CppObjectBase)enemy).Pointer] = new View
		{
			Enemy = enemy,
			Model = val,
			Entry = value2,
			Orbs = new OrbHealth(val)
		};
	}

	internal static void Tick()
	{
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		KeyValuePair<IntPtr, View>[] array = Views.ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			KeyValuePair<IntPtr, View> keyValuePair = array[i];
			View value = keyValuePair.Value;
			if ((Object)(object)value.Enemy == (Object)null || (Object)(object)value.Model == (Object)null)
			{
				value.Orbs.Dispose();
				Views.Remove(keyValuePair.Key);
				continue;
			}
			bool flag = value.Enemy.hp > 0f && ((Component)value.Enemy).gameObject.activeInHierarchy;
			if (value.Model.activeSelf != flag)
			{
				value.Model.SetActive(flag);
			}
			if (flag)
			{
				value.Enemy.renderer.forceRenderingOff = true;
				value.Orbs.Update(value.Enemy.hp / Math.Max(1f, value.Enemy.maxHp));
				if (value.Entry.Behavior == "charge")
				{
					value.Enemy.speedMultiplier = ((Time.time % 5f < 1f) ? 2.2f : 1f);
				}
				if (value.Entry.Behavior == "skitter")
				{
					value.Model.transform.localRotation = Quaternion.Euler(0f, Mathf.Sin(Time.time * 9f) * 14f, 0f);
				}
			}
		}
	}
}
[HarmonyPatch(typeof(Enemy), "InitEnemy")]
internal static class AttachEnemyModel
{
	private static void Postfix(Enemy __instance)
	{
		try
		{
			EnemyModels.Attach(__instance);
		}
		catch (Exception ex)
		{
			Plugin.Logger.LogError((object)("Wildforge enemy model failed: " + ex));
		}
	}
}
[HarmonyPatch(typeof(EnemyManager), "SpawnEnemy", new Type[]
{
	typeof(EnemyData),
	typeof(Vector3),
	typeof(int),
	typeof(bool),
	typeof(EEnemyFlag),
	typeof(bool),
	typeof(float)
})]
internal static class MixedEnemyWaves
{
	private static readonly HashSet<int> Bosses = new HashSet<int> { 7, 15, 25, 27, 34, 35, 36, 43, 50 };

	private static void Prefix(ref EnemyData enemyData)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected I4, but got Unknown
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected I4, but got Unknown
		if (Catalog.Data == null || Catalog.EnemiesById.ContainsKey((int)enemyData.enemyName) || Bosses.Contains((int)enemyData.enemyName) || Random.value > 0.4f)
		{
			return;
		}
		int biome = Random.Range(0, 6);
		int num = Random.Range(0, 100);
		foreach (Entry item in Catalog.Data.Enemies.Where((Entry e) => e.Biome == biome && !e.Boss))
		{
			num -= item.Weight;
			if (num < 0)
			{
				enemyData = DataManager.Instance.enemyData[(EEnemy)item.RuntimeId];
				break;
			}
		}
	}
}
[HarmonyPatch(typeof(EnemyManager), "SpawnBoss")]
internal static class MixedBosses
{
	private static void Prefix(ref EEnemy eEnemy)
	{
		if (Catalog.Data != null && !Catalog.EnemiesById.ContainsKey((int)eEnemy) && !(Random.value > 0.5f))
		{
			Entry[] array = Catalog.Data.Enemies.Where((Entry e) => e.Boss).ToArray();
			eEnemy = (EEnemy)array[Random.Range(0, array.Length)].RuntimeId;
		}
	}
}
[HarmonyPatch(typeof(EnemyData), "GetName")]
internal static class WildforgeEnemyName
{
	private static void Postfix(EnemyData __instance, ref string __result)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected I4, but got Unknown
		if (Catalog.EnemiesById.TryGetValue((int)__instance.enemyName, out var value))
		{
			__result = value.Name;
		}
	}
}
internal static class FullCatalog
{
	internal static readonly Dictionary<string, Texture2D> Icons = new Dictionary<string, Texture2D>();

	internal static readonly Dictionary<IntPtr, Entry> Passives = new Dictionary<IntPtr, Entry>();

	internal static readonly Dictionary<EWeapon, EWeapon> WeaponArchetypes = new Dictionary<EWeapon, EWeapon>();

	internal static Texture2D Icon(string path)
	{
		if (!Icons.TryGetValue(path, out var value))
		{
			value = (Icons[path] = TextureLoader.Load(Path.Combine(Plugin.AssetDirectory, path.Replace('/', Path.DirectorySeparatorChar))));
		}
		return value;
	}

	internal static void Register(DataManager manager)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_044a: Unknown result type (might be due to invalid IL or missing references)
		//IL_047d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_050c: Unknown result type (might be due to invalid IL or missing references)
		//IL_055e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0560: Unknown result type (might be due to invalid IL or missing references)
		//IL_056a: Expected O, but got Unknown
		//IL_0575: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_081e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0825: Expected O, but got Unknown
		//IL_0632: Unknown result type (might be due to invalid IL or missing references)
		//IL_0657: Unknown result type (might be due to invalid IL or missing references)
		//IL_0659: Unknown result type (might be due to invalid IL or missing references)
		//IL_0661: Unknown result type (might be due to invalid IL or missing references)
		//IL_0637: Unknown result type (might be due to invalid IL or missing references)
		//IL_0673: Unknown result type (might be due to invalid IL or missing references)
		//IL_0695: Unknown result type (might be due to invalid IL or missing references)
		//IL_066b: Unknown result type (might be due to invalid IL or missing references)
		//IL_063d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0643: Unknown result type (might be due to invalid IL or missing references)
		//IL_072d: Unknown result type (might be due to invalid IL or missing references)
		//IL_073f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0655: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c4: Unknown result type (might be due to invalid IL or missing references)
		Catalog.Load();
		foreach (Entry weapon2 in Catalog.Data.Weapons)
		{
			Entry entry = weapon2;
			EWeapon val = (EWeapon)entry.RuntimeId;
			WeaponData weapon;
			if (!manager.weapons.ContainsKey(val))
			{
				EWeapon val2 = WeaponArchetype(entry);
				if (!manager.weapons.ContainsKey(val2))
				{
					val2 = (EWeapon)3;
				}
				WeaponData val3 = manager.weapons[val2];
				weapon = Object.Instantiate<WeaponData>(val3);
				Content.Setup((UnlockableBase)(object)weapon, entry.Name);
				weapon.eWeapon = val;
				weapon.icon = (Texture)(object)Icon(entry.Portrait);
				weapon.AchievementRequirement = null;
				weapon.damageSourceName = "wildforge_weapon_" + entry.Id;
				weapon.baseStats = new Dictionary<EStat, float>();
				Enumerator<EStat, float> enumerator2 = val3.baseStats.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					KeyValuePair<EStat, float> current = enumerator2.Current;
					weapon.baseStats.Add(current.Key, current.Value);
				}
				if (weapon.baseStats.ContainsKey((EStat)12))
				{
					Dictionary<EStat, float> baseStats = weapon.baseStats;
					baseStats[(EStat)12] = baseStats[(EStat)12] * entry.Damage;
				}
				if (weapon.baseStats.ContainsKey((EStat)15))
				{
					Dictionary<EStat, float> baseStats = weapon.baseStats;
					baseStats[(EStat)15] = baseStats[(EStat)15] * entry.Rate;
				}
				Modify("extraShots", (EStat)16);
				Modify("extraBounce", (EStat)45);
				Modify("shotScale", (EStat)9, multiplier: true);
				Modify("areaScale", (EStat)9, multiplier: true);
				Modify("durationScale", (EStat)10, multiplier: true);
				Modify("extraMeteors", (EStat)16);
				manager.weapons.Add(val, weapon);
				manager.unsortedWeapons.Add(weapon);
				manager.unsortedUnlockables.Add((UnlockableBase)(object)weapon);
				EffectManager.weaponNamesCache[val] = weapon.damageSourceName;
				WeaponArchetypes[val] = val2;
			}
			void Modify(string key, EStat stat, bool multiplier = false)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: 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)
				if (entry.Modifiers.TryGetValue(key, out var value) && value.ValueKind == JsonValueKind.Number)
				{
					float single = value.GetSingle();
					if (weapon.baseStats.ContainsKey(stat))
					{
						weapon.baseStats[stat] = (multiplier ? (weapon.baseStats[stat] * single) : (weapon.baseStats[stat] + single));
					}
					else
					{
						weapon.baseStats[stat] = (multiplier ? single : single);
					}
				}
			}
		}
		foreach (Entry entry2 in Catalog.Data.Heroes)
		{
			ECharacter val4 = (ECharacter)entry2.RuntimeId;
			if (!manager.characterData.ContainsKey(val4))
			{
				CharacterData val5 = Object.Instantiate<CharacterData>(manager.characterData[(ECharacter)10]);
				Content.Setup((UnlockableBase)(object)val5, entry2.Name);
				val5.eCharacter = val4;
				val5.icon = (Texture)(object)Icon(entry2.Portrait);
				val5.weapon = manager.weapons[(EWeapon)Catalog.Data.Weapons.First((Entry w) => w.Id == entry2.Weapon).RuntimeId];
				val5.achievementRequirement = null;
				val5.numQuestsRequiredForVisibilityInCharacterSelection = 0;
				val5.statModifiers = new List<StatModifier>();
				val5.passive = Object.Instantiate<PassiveData>(manager.characterData[(ECharacter)10].passive);
				((Object)val5.passive).name = entry2.Perk;
				val5.passive.ePassive = (EPassive)9;
				val5.passive.icon = val5.icon;
				Object.DontDestroyOnLoad((Object)(object)val5.passive);
				Passives[((Il2CppObjectBase)val5.passive).Pointer] = entry2;
				manager.characterData.Add(val4, val5);
				manager.unsortedCharacterData.Add(val5);
				manager.unsortedUnlockables.Add((UnlockableBase)(object)val5);
				SkinData val6 = Object.Instantiate<SkinData>(manager.GetSkin((ECharacter)10, 0));
				Content.Setup((UnlockableBase)(object)val6, entry2.Name + " Default");
				val6.character = val4;
				val6.icon = val5.icon;
				val6.unlockRequirement = null;
				List<SkinData> val7 = new List<SkinData>();
				val7.Add(val6);
				manager.skinData.Add(val4, val7);
				manager.unsortedSkins.Add(val6);
			}
		}
		foreach (Entry card in Catalog.Data.Cards)
		{
			EItem val8 = (EItem)card.RuntimeId;
			if (!manager.itemData.ContainsKey(val8))
			{
				ItemData val9 = Object.Instantiate<ItemData>(manager.itemData[(EItem)35]);
				Content.Setup((UnlockableBase)(object)val9, card.Name);
				val9.eItem = val8;
				val9.icon = (Texture)(object)Icon(card.Portrait);
				val9.inItemPool = true;
				val9.rarity = (EItemRarity)card.Rarity;
				val9.unlockRequirement = null;
				val9.maxAmount = int.MaxValue;
				val9.maxAmountPerRun = int.MaxValue;
				val9.dummyItem = Content.MakeItem(val8, new ItemInventory());
				manager.itemData.Add(val8, val9);
				manager.unsortedItems.Add(val9);
				manager.unsortedUnlockables.Add((UnlockableBase)(object)val9);
			}
		}
		foreach (Entry enemy in Catalog.Data.Enemies)
		{
			EEnemy val10 = (EEnemy)enemy.RuntimeId;
			if (!manager.enemyData.ContainsKey(val10))
			{
				EEnemy val11 = (EEnemy)(enemy.Behavior switch
				{
					"boss" => 15, 
					"armored" => 3, 
					"spit" => 29, 
					"skitter" => 12, 
					_ => enemy.Flying ? 16 : 0, 
				});
				if (!manager.enemyData.ContainsKey(val11))
				{
					val11 = (EEnemy)0;
				}
				EnemyData val12 = manager.enemyData[val11];
				EnemyData val13 = Object.Instantiate<EnemyData>(val12);
				((Object)val13).name = enemy.Name;
				val13.enemyName = val10;
				val13.hp = (enemy.Boss ? ((int)enemy.Health) : Math.Max(1, (int)((float)val12.hp * enemy.Health)));
				val13.damage = Math.Max(1, (int)((float)val12.damage * enemy.Damage));
				val13.speed = val12.speed * enemy.Speed;
				val13.isFlying = enemy.Flying;
				val13.overrideHeight = enemy.Height;
				val13.colliderRadius = enemy.Radius;
				val13.colliderCenter = Vector3.up * (enemy.Height * 0.5f);
				val13.canBeElite = !enemy.Boss;
				val13.minStage = (enemy.Boss ? 1000 : 0);
				val13.canSpawnAfterTime = (enemy.Boss ? float.MaxValue : 0f);
				val13.maps = (EMap)15;
				val13.creditCost = Math.Max(0.1f, val12.creditCost * enemy.Health);
				Object.DontDestroyOnLoad((Object)(object)val13);
				manager.enemyData.Add(val10, val13);
				manager.unsortedEnemies.Add(val13);
			}
		}
		Content.Portrait = Icon(Catalog.HeroesById[87001].Portrait);
		ManualLogSource logger = Plugin.Logger;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val14 = new BepInExInfoLogInterpolatedStringHandler(90, 6, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val14).AppendLiteral("FULL MERGE registered: ");
			((BepInExLogInterpolatedStringHandler)val14).AppendFormatted<int>(Catalog.Data.Heroes.Count);
			((BepInExLogInterpolatedStringHandler)val14).AppendLiteral(" heroes, ");
			((BepInExLogInterpolatedString