Decompiled source of WC3Creatures v0.8.0

plugins/WC3Creatures/WC3Creatures.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WC3Creatures")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WC3Creatures")]
[assembly: AssemblyTitle("WC3Creatures")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WC3Creatures
{
	public class TrophyDef
	{
		public string Base = "TrophyGreydwarf";

		public float Chance = 0.15f;

		public string Name;

		public string NameRu;
	}
	public class AbilityDef
	{
		public string Clone;

		public string Anim = "spell";

		public float DamageMult = 1f;

		public float Interval;

		public string Spell;

		public float Range = 20f;

		public float MinRange;
	}
	public class AltarDef
	{
		public string Model;

		public float Health = 3000f;

		public string Item;

		public int Count = 3;

		public string Station = "piece_workbench";

		public string Name;

		public string NameRu;

		public List<DropDef> Cost = new List<DropDef>
		{
			new DropDef
			{
				Item = "Stone",
				Min = 20
			}
		};
	}
	public static class Bosses
	{
		public static void AddTrophy(CreatureDef d, CreatureConfig config)
		{
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (d.Trophy == null)
			{
				return;
			}
			string text = "WC3_Trophy_" + d.Model;
			if (!ZNetSceneHas(text))
			{
				CustomItem val = new CustomItem(text, d.Trophy.Base);
				SharedData shared = val.ItemDrop.m_itemData.m_shared;
				shared.m_name = "$item_" + text.ToLowerInvariant();
				shared.m_description = "$item_" + text.ToLowerInvariant() + "_desc";
				Sprite val2 = Icons.Get(d.Model);
				if (Object.op_Implicit((Object)(object)val2))
				{
					shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 };
				}
				Staffs.Figurine(val.ItemPrefab, d.Model, d.Boss ? 0.6f : 0.35f);
				ItemManager.Instance.AddItem(val);
				Loc.Add(new Dictionary<string, string>
				{
					{
						"item_" + text.ToLowerInvariant(),
						d.Trophy.Name ?? (d.Name + " trophy")
					},
					{
						"item_" + text.ToLowerInvariant() + "_desc",
						"A trophy from Azeroth. Offer it at a hero altar."
					}
				}, new Dictionary<string, string>
				{
					{
						"item_" + text.ToLowerInvariant(),
						d.Trophy.NameRu ?? ("Трофей: " + (d.NameRu ?? d.Name))
					},
					{
						"item_" + text.ToLowerInvariant() + "_desc",
						"Трофей из Азерота. Поднесите его к алтарю героя."
					}
				});
			}
			config.AddDropConfig(new DropConfig
			{
				Item = text,
				Chance = d.Trophy.Chance * 100f,
				MinAmount = 1,
				MaxAmount = 1,
				LevelMultiplier = false
			});
		}

		private static bool ZNetSceneHas(string name)
		{
			return Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(name));
		}

		public static void MakeBoss(CreatureDef d, Humanoid hum, List<GameObject> attacks)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			((Character)hum).m_boss = true;
			((Character)hum).m_defeatSetGlobalKey = "defeated_" + d.Id.ToLowerInvariant();
			GameObject val = ((d.MusicFrom != null) ? PrefabManager.Instance.GetPrefab(d.MusicFrom) : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				Character component = val.GetComponent<Character>();
				if (component != null)
				{
					((Character)hum).m_bossEvent = component.m_bossEvent;
				}
			}
			foreach (AbilityDef item in d.Abilities.Where((AbilityDef x) => x.Spell != null))
			{
				SpellDef spellDef = Spells.Def(item.Spell);
				if (spellDef == null || !Object.op_Implicit((Object)(object)Spells.Get(item.Spell)))
				{
					Plugin.Log.LogWarning((object)(d.Id + ": spell " + item.Spell + " unavailable"));
					continue;
				}
				CustomItem val2 = new CustomItem(d.Id + "_" + item.Spell, "GoblinShaman_attack_fireball");
				SharedData shared = val2.ItemDrop.m_itemData.m_shared;
				Spells.ApplyToAttack(spellDef, shared);
				Attack attack = shared.m_attack;
				attack.m_attackAnimation = ((item.Anim == "attack") ? "attack" : "attack2");
				attack.m_attackRandomAnimations = ((item.Anim == "attack") ? 2 : 0);
				attack.m_attackChainLevels = 0;
				attack.m_attackHeight = Mathf.Max(1.2f, ((d.Height > 0f) ? d.Height : 3f) * 0.6f);
				attack.m_attackStamina = 0f;
				shared.m_aiAttackRange = item.Range;
				shared.m_aiAttackRangeMin = item.MinRange;
				shared.m_aiAttackInterval = ((item.Interval > 0f) ? item.Interval : 8f);
				shared.m_aiTargetType = (AiTarget)0;
				if (item.DamageMult != 1f)
				{
					((DamageTypes)(ref shared.m_damages)).Modify(item.DamageMult);
				}
				ItemManager.Instance.AddItem(val2);
				attacks.Add(val2.ItemPrefab);
			}
			foreach (AbilityDef item2 in d.Abilities.Where((AbilityDef x) => x.Spell == null))
			{
				if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(item2.Clone)))
				{
					Plugin.Log.LogWarning((object)(d.Id + ": ability " + item2.Clone + " not found"));
					continue;
				}
				CustomItem val3 = new CustomItem(d.Id + "_" + item2.Clone, item2.Clone);
				SharedData shared2 = val3.ItemDrop.m_itemData.m_shared;
				Attack attack2 = shared2.m_attack;
				attack2.m_attackAnimation = ((item2.Anim == "attack") ? "attack" : "attack2");
				attack2.m_attackRandomAnimations = ((item2.Anim == "attack") ? 2 : 0);
				attack2.m_attackChainLevels = 0;
				attack2.m_attackOriginJoint = "";
				if (item2.Interval > 0f)
				{
					shared2.m_aiAttackInterval = item2.Interval;
				}
				if (item2.DamageMult != 1f)
				{
					((DamageTypes)(ref shared2.m_damages)).Modify(item2.DamageMult);
				}
				ItemManager.Instance.AddItem(val3);
				attacks.Add(val3.ItemPrefab);
			}
		}

		public static void AddAltar(CreatureDef d, GameObject bossPrefab, AssetBundle bundle)
		{
			AltarDef altar = d.Altar;
			if (altar == null)
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab(altar.Item);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				Plugin.Log.LogWarning((object)(d.Id + ": altar item " + altar.Item + " not found"));
				return;
			}
			GameObject val = bundle.LoadAsset<GameObject>("wc3_" + altar.Model);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogWarning((object)(d.Id + ": altar model " + altar.Model + " missing"));
				return;
			}
			string text = "WC3_Altar_" + d.Model;
			GameObject val2 = Buildings.MakePiece(text, val, altar.Model, "stone_wall_4x2", altar.Health, 0.6f);
			OfferingBowl val3 = val2.AddComponent<OfferingBowl>();
			val3.m_name = "$piece_" + text.ToLowerInvariant();
			val3.m_useItemText = "$piece_offerbowl_offeritem";
			val3.m_bossItem = prefab.GetComponent<ItemDrop>();
			val3.m_bossItems = altar.Count;
			val3.m_bossPrefab = bossPrefab;
			val3.m_itemPrefab = null;
			val3.m_itemSpawnPoint = val2.transform;
			val3.m_setGlobalKey = "";
			val3.m_spawnBossDelay = 4f;
			val3.m_spawnBossMinDistance = 8f;
			val3.m_spawnBossMaxDistance = 25f;
			val3.m_alertOnSpawn = true;
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("offeraltar_deer");
			OfferingBowl val4 = ((prefab2 != null) ? prefab2.GetComponentInChildren<OfferingBowl>(true) : null);
			if (Object.op_Implicit((Object)(object)val4))
			{
				val3.m_fuelAddedEffects = val4.m_fuelAddedEffects;
				val3.m_spawnBossStartEffects = val4.m_spawnBossStartEffects;
				val3.m_spawnBossDoneffects = val4.m_spawnBossDoneffects;
			}
			string name = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
			Buildings.Register(val2, text, altar.Cost, altar.Name ?? ("Altar of " + d.Name), altar.NameRu ?? ("Алтарь: " + (d.NameRu ?? d.Name)), $"Offer {altar.Count} x {name} to summon {d.Name}.", $"Поднесите {altar.Count} x {name}, чтобы призвать: {d.NameRu ?? d.Name}.", altar.Model, altar.Station);
			Plugin.Log.LogInfo((object)$"added altar {text} -> {d.Id} ({altar.Count} x {altar.Item})");
		}
	}
	public class BuildingDef
	{
		public string Id;

		public string Model;

		public string Name;

		public string NameRu;

		public string Description;

		public string DescriptionRu;

		public float Health = 1500f;

		public string Base = "stone_wall_4x2";

		public float Footprint = 0.7f;

		public string Station = "piece_stonecutter";

		public List<DropDef> Cost = new List<DropDef>
		{
			new DropDef
			{
				Item = "Stone",
				Min = 20
			}
		};
	}
	public static class Buildings
	{
		public static GameObject MakePiece(string id, GameObject model, string modelName, string basePiece, float health, float footprint)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = PrefabManager.Instance.GetPrefab(basePiece);
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(id, prefab);
			foreach (Transform item in ((IEnumerable)val.transform).Cast<Transform>().ToList())
			{
				Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
			}
			Collider[] components = val.GetComponents<Collider>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			GameObject val2 = Object.Instantiate<GameObject>(model, val.transform, false);
			((Object)val2).name = "visual";
			Animator component = val2.GetComponent<Animator>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.cullingMode = (AnimatorCullingMode)2;
			}
			Visuals.FixMaterials(val2);
			float num = 3f;
			float num2 = 3f;
			if (Defs.Models.TryGetValue(modelName, out var value))
			{
				num = value.height_m;
				num2 = value.size_m;
				val2.transform.localPosition = new Vector3(0f, (value.zmin_m < 0f) ? (0f - value.zmin_m) : 0f, 0f);
			}
			BoxCollider obj = val.AddComponent<BoxCollider>();
			obj.size = new Vector3(num2 * footprint, num, num2 * footprint);
			obj.center = new Vector3(0f, num * 0.5f, 0f);
			WearNTear component2 = val.GetComponent<WearNTear>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.m_health = health;
				component2.m_new = val2;
				component2.m_worn = val2;
				component2.m_broken = val2;
				component2.m_wet = null;
				component2.m_noRoofWear = true;
				component2.m_noSupportWear = true;
				component2.m_supports = true;
			}
			Piece component3 = val.GetComponent<Piece>();
			component3.m_name = "$piece_" + id.ToLowerInvariant();
			component3.m_description = "$piece_" + id.ToLowerInvariant() + "_desc";
			component3.m_groundOnly = true;
			component3.m_noInWater = true;
			component3.m_allowedInDungeons = false;
			return val;
		}

		public static void Register(GameObject go, string id, List<DropDef> cost, string nameEn, string nameRu, string descEn, string descRu, string model = null, string station = "piece_stonecutter")
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			Sprite val = Icons.Get(model);
			if (!Object.op_Implicit((Object)(object)val))
			{
				try
				{
					val = RenderManager.Instance.Render(go, RenderManager.IsometricRotation);
				}
				catch
				{
				}
			}
			PieceConfig val2 = new PieceConfig
			{
				Name = "$piece_" + id.ToLowerInvariant(),
				Description = "$piece_" + id.ToLowerInvariant() + "_desc",
				PieceTable = PieceTables.Hammer,
				Category = "WC3",
				CraftingStation = station,
				Icon = val,
				Requirements = ((IEnumerable<DropDef>)cost).Select((Func<DropDef, RequirementConfig>)((DropDef c) => new RequirementConfig(c.Item, c.Min, 0, true))).ToArray()
			};
			PieceManager.Instance.AddPiece(new CustomPiece(go, true, val2));
			Loc.Add(new Dictionary<string, string>
			{
				{
					"piece_" + id.ToLowerInvariant(),
					nameEn
				},
				{
					"piece_" + id.ToLowerInvariant() + "_desc",
					descEn ?? ""
				}
			}, new Dictionary<string, string>
			{
				{
					"piece_" + id.ToLowerInvariant(),
					nameRu ?? nameEn
				},
				{
					"piece_" + id.ToLowerInvariant() + "_desc",
					descRu ?? descEn ?? ""
				}
			});
		}

		public static void Add(BuildingDef b, AssetBundle bundle)
		{
			GameObject val = bundle.LoadAsset<GameObject>("wc3_" + b.Model);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogError((object)(b.Id + ": model wc3_" + b.Model + " missing"));
				return;
			}
			Register(MakePiece(b.Id, val, b.Model, b.Base, b.Health, b.Footprint), b.Id, b.Cost, b.Name, b.NameRu, b.Description, b.DescriptionRu, b.Model, b.Station);
			Plugin.Log.LogInfo((object)("added building " + b.Id));
		}
	}
	public class ConsumableDef
	{
		public string Id;

		public string Icon;

		public string Name;

		public string NameRu;

		public string Description;

		public string DescriptionRu;

		public string Base = "MeadHealthMinor";

		public bool KeepBaseEffect;

		public string Station = "piece_cauldron";

		public int StationLevel = 1;

		public int Amount = 1;

		public List<DropDef> Recipe = new List<DropDef>();

		public float Duration = 60f;

		public float Speed;

		public float RunStaminaDrain;

		public float HealthRegen = 1f;

		public float StaminaRegen = 1f;

		public float EitrRegen = 1f;

		public float CarryWeight;

		public float PhysicalDamage;

		public float FireDamage;

		public float FrostDamage;

		public float LightningDamage;

		public float PoisonDamage;

		public float SpiritDamage;

		public Dictionary<string, string> Resist = new Dictionary<string, string>();
	}
	public static class Consumables
	{
		public static void Add(ConsumableDef c)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: 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_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(c.Base)))
			{
				Plugin.Log.LogError((object)(c.Id + ": base " + c.Base + " not found"));
				return;
			}
			string text = c.Id.ToLowerInvariant();
			RequirementConfig[] array = c.Recipe.Where((DropDef r) => Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(r.Item))).Select((Func<DropDef, RequirementConfig>)((DropDef r) => new RequirementConfig(r.Item, r.Min, 0, false))).ToArray();
			CustomItem val = new CustomItem(c.Id, c.Base, new ItemConfig
			{
				Name = "$item_" + text,
				Description = "$item_" + text + "_desc",
				Amount = Mathf.Max(1, c.Amount),
				CraftingStation = c.Station,
				MinStationLevel = c.StationLevel,
				Requirements = array
			});
			SharedData shared = val.ItemDrop.m_itemData.m_shared;
			Sprite val2 = Icons.Get(c.Icon);
			if (Object.op_Implicit((Object)(object)val2))
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 };
			}
			if (!c.KeepBaseEffect)
			{
				SE_Stats val3 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val3).name = "SE_" + c.Id;
				((StatusEffect)val3).m_name = "$item_" + text;
				((StatusEffect)val3).m_tooltip = "$item_" + text + "_desc";
				((StatusEffect)val3).m_icon = val2;
				((StatusEffect)val3).m_ttl = c.Duration;
				val3.m_speedModifier = c.Speed;
				val3.m_runStaminaDrainModifier = c.RunStaminaDrain;
				val3.m_healthRegenMultiplier = c.HealthRegen;
				val3.m_staminaRegenMultiplier = c.StaminaRegen;
				val3.m_eitrRegenMultiplier = c.EitrRegen;
				val3.m_addMaxCarryWeight = c.CarryWeight;
				val3.m_percentigeDamageModifiers = new DamageTypes
				{
					m_blunt = c.PhysicalDamage,
					m_slash = c.PhysicalDamage,
					m_pierce = c.PhysicalDamage,
					m_fire = c.FireDamage,
					m_frost = c.FrostDamage,
					m_lightning = c.LightningDamage,
					m_poison = c.PoisonDamage,
					m_spirit = c.SpiritDamage
				};
				val3.m_mods = ((IEnumerable<KeyValuePair<string, string>>)c.Resist).Select((Func<KeyValuePair<string, string>, DamageModPair>)((KeyValuePair<string, string> kv) => new DamageModPair
				{
					m_type = (DamageType)Enum.Parse(typeof(DamageType), kv.Key, ignoreCase: true),
					m_modifier = (DamageModifier)Enum.Parse(typeof(DamageModifier), kv.Value, ignoreCase: true)
				})).ToList();
				ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)val3, false));
				shared.m_consumeStatusEffect = (StatusEffect)(object)val3;
			}
			ItemManager.Instance.AddItem(val);
			Loc.Add(new Dictionary<string, string>
			{
				{
					"item_" + text,
					c.Name
				},
				{
					"item_" + text + "_desc",
					c.Description ?? ""
				}
			}, new Dictionary<string, string>
			{
				{
					"item_" + text,
					c.NameRu ?? c.Name
				},
				{
					"item_" + text + "_desc",
					c.DescriptionRu ?? c.Description ?? ""
				}
			});
			Plugin.Log.LogInfo((object)$"added consumable {c.Id} ({array.Length} reqs)");
		}
	}
	public static class DamageLog
	{
		public class Entry
		{
			public string Attacker;

			public string Victim;

			public string Kind;

			public float Total;

			public DamageTypes D;

			public float Time;
		}

		public static readonly List<Entry> Entries = new List<Entry>();

		private static bool _patched;

		public static void Enable()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if (!_patched)
			{
				new Harmony("wc3.creatures.damagelog").Patch((MethodBase)AccessTools.Method(typeof(Character), "Damage", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DamageLog), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patched = true;
			}
		}

		private static void Prefix(Character __instance, HitData hit)
		{
			//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_008d: Unknown result type (might be due to invalid IL or missing references)
			Character val = ((hit != null) ? hit.GetAttacker() : null);
			if (Object.op_Implicit((Object)(object)val) && ((Object)val).name.StartsWith("WC3_"))
			{
				Entries.Add(new Entry
				{
					Attacker = ((Object)val).name.Replace("(Clone)", ""),
					Victim = ((Object)__instance).name.Replace("(Clone)", ""),
					Total = hit.GetTotalDamage(),
					D = hit.m_damage,
					Time = Time.time,
					Kind = Profile(hit.m_damage)
				});
			}
		}

		private static string Profile(DamageTypes d)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			List<string> parts = new List<string>();
			P("blunt", d.m_blunt);
			P("slash", d.m_slash);
			P("pierce", d.m_pierce);
			P("fire", d.m_fire);
			P("frost", d.m_frost);
			P("poison", d.m_poison);
			P("lightning", d.m_lightning);
			P("spirit", d.m_spirit);
			return string.Join("+", parts);
			void P(string n, float v)
			{
				if (v > 0.5f)
				{
					parts.Add(n);
				}
			}
		}

		public static string Detail(int n)
		{
			return string.Join("\n", from e in Entries.Skip(Math.Max(0, Entries.Count - n))
				select $"t={e.Time:0.00} {e.Attacker} -> {e.Victim} [{e.Kind}] {e.Total:0}");
		}

		public static string Summary()
		{
			if (Entries.Count == 0)
			{
				return "no WC3 hits recorded";
			}
			return string.Join("\n", from e in Entries
				group e by e.Attacker + " [" + e.Kind + "]" into g
				select $"{g.Key}: hits {g.Count()}, avg {g.Average((Entry e) => e.Total):0}, max {g.Max((Entry e) => e.Total):0}");
		}
	}
	public class CreatureDef
	{
		public string Id;

		public string Model;

		public string Base;

		public string Name;

		public string NameRu;

		public float Health;

		public float Height;

		public float Radius;

		public float WalkSpeed;

		public float RunSpeed;

		public float Blunt;

		public float Slash;

		public float Pierce;

		public float Fire;

		public float Frost;

		public float Poison;

		public float Lightning;

		public float Spirit;

		public float AttackInterval = 2f;

		public float AttackRangeMul = 1f;

		public float? VisualOffsetY;

		public string Biome = "Meadows";

		public float MinAltitude = -1000f;

		public float MaxAltitude = 1000f;

		public float SpawnChance = 20f;

		public float SpawnInterval = 300f;

		public int MaxSpawned = 3;

		public int GroupMin = 1;

		public int GroupMax = 2;

		public bool Night = true;

		public bool Day = true;

		public List<DropDef> Drops = new List<DropDef>();

		public TrophyDef Trophy;

		public bool Boss;

		public bool NoSpawn;

		public string Faction;

		public float ViewRange;

		public string MusicFrom;

		public List<AbilityDef> Abilities = new List<AbilityDef>();

		public AltarDef Altar;

		public Biome BiomeEnum => ((IEnumerable<string>)Biome.Split(new char[1] { '|' })).Select((Func<string, Biome>)((string b) => (Biome)Enum.Parse(typeof(Biome), b.Trim(), ignoreCase: true))).Aggregate((Biome)0, (Biome a, Biome b) => (Biome)(a | b));
	}
	public class ModelInfo
	{
		public float height_m;

		public float size_m;

		public float zmin_m;

		public float scale;
	}
	public class DropDef
	{
		public string Item;

		public int Min = 1;

		public int Max = 1;

		public float Chance = 1f;

		public int PerLevel = -1;

		public int UpgradeCost
		{
			get
			{
				if (PerLevel < 0)
				{
					if (!Item.StartsWith("WC3_Essence_") && !Item.StartsWith("WC3_Trophy_"))
					{
						return Math.Max(1, (Min + 1) / 2);
					}
					return 1;
				}
				return PerLevel;
			}
		}
	}
	public class DefFile
	{
		public List<CreatureDef> creatures = new List<CreatureDef>();

		public List<BuildingDef> buildings = new List<BuildingDef>();

		public List<WeaponDef> weapons = new List<WeaponDef>();

		public List<LairDef> lairs = new List<LairDef>();

		public List<TrinketDef> trinkets = new List<TrinketDef>();

		public List<SpellDef> spells = new List<SpellDef>();

		public List<ConsumableDef> consumables = new List<ConsumableDef>();

		public List<StaffDef> staffs = new List<StaffDef>();

		public List<MaterialDef> materials = new List<MaterialDef>();
	}
	public static class Defs
	{
		public static List<CreatureDef> All = new List<CreatureDef>();

		public static List<BuildingDef> Buildings = new List<BuildingDef>();

		public static List<WeaponDef> Weapons = new List<WeaponDef>();

		public static List<LairDef> Lairs = new List<LairDef>();

		public static List<TrinketDef> Trinkets = new List<TrinketDef>();

		public static List<SpellDef> Spells = new List<SpellDef>();

		public static List<ConsumableDef> Consumables = new List<ConsumableDef>();

		public static List<StaffDef> Staffs = new List<StaffDef>();

		public static List<MaterialDef> Materials = new List<MaterialDef>();

		public static Dictionary<string, ModelInfo> Models = new Dictionary<string, ModelInfo>();

		private static string Read(string name)
		{
			string path = Path.Combine(Path.GetDirectoryName(typeof(Defs).Assembly.Location), name);
			if (File.Exists(path))
			{
				return File.ReadAllText(path);
			}
			using Stream stream = typeof(Defs).Assembly.GetManifestResourceStream(name);
			if (stream == null)
			{
				return null;
			}
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		public static string Load()
		{
			string text = null;
			string text2 = Path.Combine(Path.GetDirectoryName(typeof(Defs).Assembly.Location), "creatures.json");
			string result;
			if (File.Exists(text2))
			{
				text = File.ReadAllText(text2);
				result = text2;
			}
			else
			{
				using (Stream stream = typeof(Defs).Assembly.GetManifestResourceStream("creatures.json"))
				{
					using StreamReader streamReader = new StreamReader(stream);
					text = streamReader.ReadToEnd();
				}
				result = "embedded";
			}
			DefFile defFile = JsonConvert.DeserializeObject<DefFile>(text);
			All = defFile.creatures;
			Buildings = defFile.buildings ?? new List<BuildingDef>();
			Weapons = defFile.weapons ?? new List<WeaponDef>();
			Lairs = defFile.lairs ?? new List<LairDef>();
			Trinkets = defFile.trinkets ?? new List<TrinketDef>();
			Spells = defFile.spells ?? new List<SpellDef>();
			Consumables = defFile.consumables ?? new List<ConsumableDef>();
			Staffs = defFile.staffs ?? new List<StaffDef>();
			Materials = defFile.materials ?? new List<MaterialDef>();
			string text3 = Read("models.json");
			if (text3 != null)
			{
				Models = JsonConvert.DeserializeObject<Dictionary<string, ModelInfo>>(text3);
			}
			return result;
		}
	}
	public class DevMode : MonoBehaviour
	{
		public static string CharName = "Clab";

		public static string WorldName = "clabworld";

		private string _dir;

		private string _cmd;

		private string _out;

		private int _menuStep;

		private float _t;

		private float _nextPoll;

		private bool _inGameSetup;

		private bool _cam;

		private bool _camPiece;

		private bool _camPlayer;

		private bool _camFx;

		private float _camDist;

		private float _camYaw = 25f;

		public static bool Requested(out string character, out string world)
		{
			string[] commandLineArgs = Environment.GetCommandLineArgs();
			int num = Array.IndexOf(commandLineArgs, "-wc3dev");
			character = ((num >= 0 && commandLineArgs.Length > num + 1 && !commandLineArgs[num + 1].StartsWith("-")) ? commandLineArgs[num + 1] : CharName);
			world = ((num >= 0 && commandLineArgs.Length > num + 2 && !commandLineArgs[num + 2].StartsWith("-")) ? commandLineArgs[num + 2] : WorldName);
			return num >= 0;
		}

		private void OnEnable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(PhotoCamera));
		}

		private void OnDisable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(PhotoCamera));
		}

		private void PhotoCamera(Camera cam)
		{
			//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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: 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_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: 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_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: 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_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: 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_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			if (!_cam || !Object.op_Implicit((Object)(object)GameCamera.instance) || (Object)(object)((Component)cam).gameObject != (Object)(object)((Component)GameCamera.instance).gameObject || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			Vector3 pp = ((Component)Player.m_localPlayer).transform.position;
			Transform val = (from c in Character.GetAllCharacters()
				where Object.op_Implicit((Object)(object)c) && ((Object)c).name.StartsWith("WC3_")
				orderby Vector3.Distance(((Component)c).transform.position, pp)
				select ((Component)c).transform).FirstOrDefault();
			if (_camPlayer)
			{
				val = ((Component)Player.m_localPlayer).transform;
			}
			else if (_camFx)
			{
				val = ((IEnumerable<Transform>)Object.FindObjectsByType<Transform>((FindObjectsSortMode)0)).FirstOrDefault((Func<Transform, bool>)((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "WC3FX_TEST"));
			}
			else if (_camPiece)
			{
				val = (from pc in Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0)
					where ((Object)pc).name.StartsWith("WC3_") && (Object.op_Implicit((Object)(object)((Component)pc).GetComponent<Piece>()) || Object.op_Implicit((Object)(object)((Component)pc).GetComponent<Destructible>()))
					orderby Vector3.Distance(((Component)pc).transform.position, pp)
					select ((Component)pc).transform).FirstOrDefault() ?? val;
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = (from c in Object.FindObjectsByType<WC3Corpse>((FindObjectsSortMode)0)
					orderby Vector3.Distance(((Component)c).transform.position, pp)
					select ((Component)c).transform).FirstOrDefault();
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Bounds val2 = default(Bounds);
			((Bounds)(ref val2))..ctor(val.position, Vector3.zero);
			if (_camPlayer)
			{
				((Bounds)(ref val2))..ctor(val.position + Vector3.up * 1.1f, new Vector3(1f, 2.2f, 1f));
			}
			else if (_camFx)
			{
				((Bounds)(ref val2))..ctor(val.position + Vector3.up * 1.2f, new Vector3(3f, 3f, 3f));
			}
			else
			{
				Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>();
				foreach (Renderer val3 in componentsInChildren)
				{
					((Bounds)(ref val2)).Encapsulate(val3.bounds);
				}
			}
			float num2 = Mathf.Max(new float[3]
			{
				((Bounds)(ref val2)).size.x,
				((Bounds)(ref val2)).size.y,
				((Bounds)(ref val2)).size.z
			});
			float num3 = ((_camDist > 0f) ? _camDist : Mathf.Max(3f, num2 * 1.4f));
			Vector3 val4 = Quaternion.Euler(0f, _camYaw, 0f) * val.forward;
			Vector3 val5 = ((Bounds)(ref val2)).center + val4 * num3 + Vector3.up * num2 * 0.25f;
			Vector3 val6 = val5 - ((Bounds)(ref val2)).center;
			foreach (RaycastHit item in from h in Physics.RaycastAll(((Bounds)(ref val2)).center, ((Vector3)(ref val6)).normalized, ((Vector3)(ref val6)).magnitude)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(val) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Character>()))
				{
					val5 = ((Bounds)(ref val2)).center + ((Vector3)(ref val6)).normalized * Mathf.Max(1.5f, ((RaycastHit)(ref current)).distance - 0.3f);
					break;
				}
			}
			((Component)cam).transform.position = val5;
			((Component)cam).transform.LookAt(((Bounds)(ref val2)).center);
		}

		private void Awake()
		{
			_dir = Path.Combine(Paths.BepInExRootPath, "wc3dev");
			Directory.CreateDirectory(_dir);
			_cmd = Path.Combine(_dir, "cmd.txt");
			_out = Path.Combine(_dir, "out.log");
			File.WriteAllText(_out, $"[{DateTime.Now:HH:mm:ss}] dev mode on: {CharName} / {WorldName}\n");
		}

		private void Out(string s)
		{
			File.AppendAllText(_out, $"[{DateTime.Now:HH:mm:ss}] {s}\n");
			Plugin.Log.LogInfo((object)("[dev] " + s));
		}

		private void Update()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			_t += Time.unscaledDeltaTime;
			try
			{
				AutoStart();
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Character)Player.m_localPlayer).InIntro() && !_inGameSetup && _t > 3f)
				{
					_inGameSetup = true;
					Run("devcommands");
					Run("god");
					Run("nocost");
					Out("in game: " + ((object)((Component)Player.m_localPlayer).transform.position/*cast due to .constrained prefix*/).ToString());
				}
				if (!(Time.unscaledTime > _nextPoll))
				{
					return;
				}
				_nextPoll = Time.unscaledTime + 0.5f;
				if (!File.Exists(_cmd))
				{
					return;
				}
				string[] source = File.ReadAllLines(_cmd);
				File.Delete(_cmd);
				foreach (string item in from x in source
					select x.Trim() into x
					where x.Length > 0
					select x)
				{
					Run(item);
				}
			}
			catch (Exception ex)
			{
				Out("error: " + ex);
			}
		}

		private void AutoStart()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			FejdStartup instance = FejdStartup.instance;
			if (!Object.op_Implicit((Object)(object)instance) || _menuStep >= 4 || _t < 2f + (float)_menuStep * 1.5f)
			{
				return;
			}
			Traverse val = Traverse.Create((object)instance);
			switch (_menuStep)
			{
			case 0:
				if (!val.Field<GameObject>("m_mainMenu").Value.activeInHierarchy)
				{
					return;
				}
				instance.OnStartGame();
				break;
			case 1:
			{
				List<PlayerProfile> value2 = val.Field<List<PlayerProfile>>("m_profiles").Value;
				int num = value2.FindIndex((PlayerProfile p) => string.Equals(p.GetName(), CharName, StringComparison.OrdinalIgnoreCase));
				if (num < 0)
				{
					PlayerProfile val2 = new PlayerProfile(CharName, (FileSource)2);
					val2.SetName(CharName);
					val2.Save();
					value2.Add(val2);
					num = value2.Count - 1;
					Out("created test character '" + CharName + "' (others: " + string.Join(", ", from p in value2.Take(value2.Count - 1)
						select p.GetName()) + ")");
				}
				value2[num].m_firstSpawn = false;
				val.Field("m_profileIndex").SetValue((object)num);
				val.Method("ShowCharacterSelection", Array.Empty<object>()).GetValue();
				instance.OnCharacterStart();
				break;
			}
			case 2:
			{
				World value = val.Method("FindWorld", new object[1] { WorldName }).GetValue<World>();
				if (value == null)
				{
					Out("world '" + WorldName + "' not found");
					_menuStep = 99;
					return;
				}
				val.Field("m_world").SetValue((object)value);
				break;
			}
			case 3:
				Out("starting world " + WorldName);
				instance.OnWorldStart();
				break;
			}
			_menuStep++;
		}

		private unsafe void Run(string line)
		{
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07da: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d2c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ed4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f00: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f05: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f1c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f21: Unknown result type (might be due to invalid IL or missing references)
			//IL_0999: Unknown result type (might be due to invalid IL or missing references)
			//IL_099e: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a05: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a14: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a23: Unknown result type (might be due to invalid IL or missing references)
			//IL_290f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2914: Unknown result type (might be due to invalid IL or missing references)
			//IL_291c: Unknown result type (might be due to invalid IL or missing references)
			//IL_2921: Unknown result type (might be due to invalid IL or missing references)
			//IL_2926: Unknown result type (might be due to invalid IL or missing references)
			//IL_292b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2930: Unknown result type (might be due to invalid IL or missing references)
			//IL_2931: Unknown result type (might be due to invalid IL or missing references)
			//IL_2936: Unknown result type (might be due to invalid IL or missing references)
			//IL_293b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2945: Expected O, but got Unknown
			//IL_1f2d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f32: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f37: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f3c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f40: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f45: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f51: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f55: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f5a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f5f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f68: Unknown result type (might be due to invalid IL or missing references)
			//IL_1961: Unknown result type (might be due to invalid IL or missing references)
			//IL_1970: Unknown result type (might be due to invalid IL or missing references)
			//IL_197f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1fc0: Unknown result type (might be due to invalid IL or missing references)
			//IL_1fc2: Unknown result type (might be due to invalid IL or missing references)
			//IL_1fc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_1fc9: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ffa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d3f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d4e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d58: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d60: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d65: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d6a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d71: 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_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_0689: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06af: Unknown result type (might be due to invalid IL or missing references)
			//IL_12bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_12c4: Expected I4, but got Unknown
			//IL_0da4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0da6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0db0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0db5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0735: Unknown result type (might be due to invalid IL or missing references)
			//IL_20d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_20dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_20e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_282d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2839: Unknown result type (might be due to invalid IL or missing references)
			//IL_284a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e04: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e1b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e1d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e2c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e48: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e59: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e65: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e77: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e79: Unknown result type (might be due to invalid IL or missing references)
			//IL_21ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_2204: Unknown result type (might be due to invalid IL or missing references)
			//IL_2208: Unknown result type (might be due to invalid IL or missing references)
			//IL_218e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2193: Unknown result type (might be due to invalid IL or missing references)
			Out("> " + line);
			string[] parts = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			Vector3 val9;
			switch (parts[0].ToLowerInvariant())
			{
			case "wc3state":
				State((parts.Length > 1) ? float.Parse(parts[1]) : 40f);
				break;
			case "wc3cam":
				_cam = parts.Length < 2 || parts[1] != "off";
				_camPiece = parts.Length > 1 && parts[1] == "piece";
				_camPlayer = parts.Length > 1 && parts[1] == "player";
				_camFx = parts.Length > 1 && parts[1] == "fx";
				_camDist = ((parts.Length > 2) ? float.Parse(parts[2], CultureInfo.InvariantCulture) : 0f);
				_camYaw = ((parts.Length > 3) ? float.Parse(parts[3], CultureInfo.InvariantCulture) : 25f);
				Out("photo camera " + (_cam ? "on" : "off"));
				break;
			case "wc3reload":
				Out(Plugin.Reload());
				break;
			case "wc3spawn":
			{
				Player localPlayer8 = Player.m_localPlayer;
				GameObject prefab2 = ZNetScene.instance.GetPrefab(parts[1]);
				if (!Object.op_Implicit((Object)(object)localPlayer8) || !Object.op_Implicit((Object)(object)prefab2))
				{
					Out("wc3spawn: no player or prefab " + parts[1]);
					break;
				}
				float num10 = ((parts.Length > 2) ? float.Parse(parts[2], CultureInfo.InvariantCulture) : 6f);
				val9 = Vector3.ProjectOnPlane(((Character)localPlayer8).GetLookDir(), Vector3.up);
				Vector3 normalized = ((Vector3)(ref val9)).normalized;
				Vector3 val12 = ((Component)localPlayer8).transform.position + normalized * num10;
				val12.y = ZoneSystem.instance.GetGroundHeight(val12) + 0.2f;
				GameObject val13 = Object.Instantiate<GameObject>(prefab2, val12, Quaternion.LookRotation(-normalized));
				Character component6 = val13.GetComponent<Character>();
				if (parts.Length > 3 && Object.op_Implicit((Object)(object)component6) && int.TryParse(parts[3], out var result))
				{
					component6.SetLevel(result);
				}
				if (parts.Contains("passive") && Object.op_Implicit((Object)(object)component6))
				{
					BaseAI component7 = val13.GetComponent<BaseAI>();
					if (Object.op_Implicit((Object)(object)component7))
					{
						((Behaviour)component7).enabled = false;
					}
				}
				Out($"spawned {parts[1]} at {val12}");
				break;
			}
			case "wc3face":
			{
				Player pl4 = Player.m_localPlayer;
				Character val24 = (from c in Character.GetAllCharacters()
					where (Object)(object)c != (Object)(object)pl4 && ((Object)c).name.StartsWith("WC3_")
					orderby Vector3.Distance(((Component)c).transform.position, ((Component)pl4).transform.position)
					select c).FirstOrDefault();
				if (!Object.op_Implicit((Object)(object)val24))
				{
					Out("wc3face: nothing");
					break;
				}
				val9 = val24.GetCenterPoint() - ((Character)pl4).GetEyePoint();
				Vector3 normalized3 = ((Vector3)(ref val9)).normalized;
				((Component)pl4).transform.rotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(normalized3, Vector3.up));
				pl4.SetMouseLookForward(true);
				((Character)pl4).SetLookDir(normalized3, 0f);
				Out("facing " + ((Object)val24).name);
				break;
			}
			case "wc3aggro":
			{
				Player localPlayer5 = Player.m_localPlayer;
				int num7 = 0;
				foreach (Character item in from c in Character.GetAllCharacters()
					where ((Object)c).name.StartsWith("WC3_")
					select c)
				{
					MonsterAI component4 = ((Component)item).GetComponent<MonsterAI>();
					ZNetView component5 = ((Component)item).GetComponent<ZNetView>();
					if (Object.op_Implicit((Object)(object)component4) && Object.op_Implicit((Object)(object)component5) && component5.IsValid() && !item.IsDead())
					{
						((Behaviour)component4).enabled = true;
						((BaseAI)component4).SetHuntPlayer(true);
						try
						{
							Traverse.Create((object)component4).Method("SetAlerted", new object[1] { true }).GetValue();
						}
						catch
						{
						}
						Traverse.Create((object)component4).Field("m_targetCreature").SetValue((object)localPlayer5);
						num7++;
					}
				}
				Out($"aggro {num7}");
				break;
			}
			case "wc3equip":
			{
				Player localPlayer7 = Player.m_localPlayer;
				GameObject prefab = ZNetScene.instance.GetPrefab(parts[1]);
				if (!Object.op_Implicit((Object)(object)prefab))
				{
					Out("wc3equip: no prefab " + parts[1]);
					break;
				}
				Inventory inventory2 = ((Humanoid)localPlayer7).GetInventory();
				inventory2.AddItem(prefab, 1);
				ItemData val11 = ((IEnumerable<ItemData>)inventory2.GetAllItems()).LastOrDefault((Func<ItemData, bool>)((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == parts[1]));
				((Humanoid)localPlayer7).EquipItem(val11, true);
				DamageTypes damage = val11.GetDamage();
				Out($"equipped {parts[1]}: blunt {damage.m_blunt:0} slash {damage.m_slash:0} pierce {damage.m_pierce:0} fire {damage.m_fire:0} frost {damage.m_frost:0} lightning {damage.m_lightning:0} spirit {damage.m_spirit:0} poison {damage.m_poison:0}");
				break;
			}
			case "wc3swing":
			{
				Player localPlayer = Player.m_localPlayer;
				bool flag = ((Character)localPlayer).StartAttack((Character)null, parts.Length > 1 && parts[1] == "secondary");
				ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon();
				Out($"swing {flag}: canMove={((Character)localPlayer).CanMove()} inAttack={((Character)localPlayer).InAttack()} minor={((Character)localPlayer).InMinorAction()} stamina={localPlayer.GetStamina():0} " + $"weapon={currentWeapon?.m_shared.m_name} cost={currentWeapon?.m_shared.m_attack.m_attackStamina} onGround={((Character)localPlayer).IsOnGround()} teleporting={((Character)localPlayer).IsTeleporting()}");
				break;
			}
			case "wc3tree":
			{
				GameObject prefab3 = ZNetScene.instance.GetPrefab(parts[1]);
				if (!Object.op_Implicit((Object)(object)prefab3))
				{
					Out("wc3tree: no prefab");
					break;
				}
				StringBuilder sb = new StringBuilder();
				Walk(prefab3.transform, 0);
				Out("tree\n" + sb);
				break;
			}
			case "wc3sfx":
			{
				IEnumerable<string> values = from a in Object.FindObjectsByType<AudioSource>((FindObjectsSortMode)0)
					where a.isPlaying && Object.op_Implicit((Object)(object)a.clip)
					select ((Object)((Component)a).gameObject).name.Replace("(Clone)", "") + ":" + ((Object)a.clip).name;
				Out("playing: " + string.Join(", ", values));
				break;
			}
			case "wc3offer":
			{
				Player pl3 = Player.m_localPlayer;
				OfferingBowl val17 = (from b in Object.FindObjectsByType<OfferingBowl>((FindObjectsSortMode)0)
					orderby Vector3.Distance(((Component)b).transform.position, ((Component)pl3).transform.position)
					select b).FirstOrDefault();
				if (!Object.op_Implicit((Object)(object)val17))
				{
					Out("wc3offer: no altar");
					break;
				}
				Inventory inventory3 = ((Humanoid)pl3).GetInventory();
				string itemName = ((Object)((Component)val17.m_bossItem).gameObject).name;
				inventory3.AddItem(((Component)val17.m_bossItem).gameObject, val17.m_bossItems);
				ItemData val18 = ((IEnumerable<ItemData>)inventory3.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == itemName));
				bool flag2 = val18 != null && val17.UseItem((Humanoid)(object)pl3, val18);
				Out($"offered {val17.m_bossItems} x {itemName} at {((Object)val17).name}: {flag2}");
				break;
			}
			case "wc3open":
			{
				Player localPlayer4 = Player.m_localPlayer;
				Vector3 position = ((Component)localPlayer4).transform.position;
				float num6 = default(float);
				for (int num4 = 20; num4 <= 200; num4 += 15)
				{
					for (int num5 = 0; num5 < 360; num5 += 30)
					{
						Vector3 val8 = position + Quaternion.Euler(0f, (float)num5, 0f) * Vector3.forward * (float)num4;
						if (ZoneSystem.instance.GetSolidHeight(val8, ref num6, 1000))
						{
							val8.y = num6;
							if (!(num6 < ZoneSystem.instance.m_waterLevel + 1f) && Physics.OverlapSphere(val8 + Vector3.up * 2f, 7f).Count((Collider c) => !c.isTrigger && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<Heightmap>()) && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<Character>())) <= 1 && !(Mathf.Abs(ZoneSystem.instance.GetGroundHeight(val8 + Vector3.forward * 6f) - num6) + Mathf.Abs(ZoneSystem.instance.GetGroundHeight(val8 + Vector3.right * 6f) - num6) > 1.5f))
							{
								((Character)localPlayer4).TeleportTo(val8 + Vector3.up * 0.3f, ((Component)localPlayer4).transform.rotation, false);
								val9 = val8;
								Out("open spot " + ((object)(*(Vector3*)(&val9))/*cast due to .constrained prefix*/).ToString());
								return;
							}
						}
					}
				}
				Out("wc3open: nothing found");
				break;
			}
			case "wc3pos":
			{
				Player localPlayer6 = Player.m_localPlayer;
				Transform transform = ((Component)localPlayer6).transform;
				transform.position += new Vector3(float.Parse(parts[1]), float.Parse(parts[2]), float.Parse(parts[3]));
				val9 = ((Component)localPlayer6).transform.position;
				Out("moved to " + ((object)(*(Vector3*)(&val9))/*cast due to .constrained prefix*/).ToString());
				break;
			}
			case "wc3clear":
				foreach (Character item2 in (from c in Character.GetAllCharacters()
					where ((Object)c).name.StartsWith("WC3_")
					select c).ToList())
				{
					ZNetView component9 = ((Component)item2).GetComponent<ZNetView>();
					if (component9 != null)
					{
						component9.Destroy();
					}
				}
				foreach (Piece item3 in (from pc in Object.FindObjectsByType<Piece>((FindObjectsSortMode)0)
					where ((Object)pc).name.StartsWith("WC3_")
					select pc).ToList())
				{
					ZNetView component10 = ((Component)item3).GetComponent<ZNetView>();
					if (component10 != null)
					{
						component10.Destroy();
					}
				}
				foreach (ZNetView item4 in (from v in Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0)
					where ((Object)v).name.StartsWith("WC3_Lair")
					select v).ToList())
				{
					item4.Destroy();
				}
				Out("cleared WC3 creatures");
				break;
			case "wc3give":
			{
				Inventory inventory5 = ((Humanoid)Player.m_localPlayer).GetInventory();
				int num14 = ((parts.Length <= 2) ? 1 : int.Parse(parts[2]));
				int num15 = 0;
				string pfx = parts[1].TrimEnd(new char[1] { '*' });
				foreach (GameObject item5 in ZNetScene.instance.m_prefabs.Where((GameObject p) => Object.op_Implicit((Object)(object)p) && Object.op_Implicit((Object)(object)p.GetComponent<ItemDrop>()) && ((!parts[1].EndsWith("*")) ? (((Object)p).name == parts[1]) : ((Object)p).name.StartsWith(pfx))))
				{
					inventory5.AddItem(item5, num14);
					num15++;
				}
				Out($"gave {num15} item types");
				break;
			}
			case "wc3inv":
				if (parts.Length > 1 && parts[1] == "off")
				{
					InventoryGui.instance.Hide();
				}
				else
				{
					InventoryGui.instance.Show((Container)null, 1);
				}
				Out("inventory " + ((parts.Length > 1) ? "closed" : "open"));
				break;
			case "wc3buildmenu":
			{
				Player localPlayer10 = Player.m_localPlayer;
				Inventory inventory4 = ((Humanoid)localPlayer10).GetInventory();
				ItemData val19 = ((IEnumerable<ItemData>)inventory4.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == "Hammer"));
				if (val19 == null)
				{
					inventory4.AddItem(ZNetScene.instance.GetPrefab("Hammer"), 1);
					val19 = inventory4.GetAllItems().Last((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == "Hammer");
				}
				if (!((Humanoid)localPlayer10).IsItemEquiped(val19))
				{
					((Humanoid)localPlayer10).EquipItem(val19, true);
				}
				PieceTable value = Traverse.Create((object)localPlayer10).Field("m_buildPieces").GetValue<PieceTable>();
				if (!Object.op_Implicit((Object)(object)value))
				{
					Out("no piece table yet, run again");
					break;
				}
				if (!Hud.IsPieceSelectionVisible())
				{
					Hud.instance.TogglePieceSelection();
				}
				List<List<Piece>> value2 = Traverse.Create((object)value).Field("m_availablePieces").GetValue<List<List<Piece>>>();
				for (int num12 = 0; num12 < 40; num12++)
				{
					int num13 = (int)value.GetSelectedCategory();
					if (value2 != null && num13 < value2.Count && value2[num13].Any((Piece x) => ((Object)x).name.StartsWith("WC3_")))
					{
						Out($"build menu on tab {num13}: {value2[num13].Count} pieces");
						return;
					}
					value.NextCategory();
				}
				Out("build menu: WC3 tab not found");
				break;
			}
			case "wc3icons":
			{
				StringBuilder stringBuilder2 = new StringBuilder();
				foreach (GameObject item6 in (from p in ZNetScene.instance.m_prefabs.Concat(ObjectDB.instance.m_items)
					where Object.op_Implicit((Object)(object)p) && ((Object)p).name.StartsWith("WC3_")
					select p).Distinct())
				{
					Piece component2 = item6.GetComponent<Piece>();
					ItemDrop component3 = item6.GetComponent<ItemDrop>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						stringBuilder2.Append(((Object)item6).name + ": " + (Object.op_Implicit((Object)(object)component2.m_icon) ? ((Object)component2.m_icon).name : "none") + " station=" + (Object.op_Implicit((Object)(object)component2.m_craftingStation) ? ((Object)component2.m_craftingStation).name : "none") + "\n");
					}
					else if (Object.op_Implicit((Object)(object)component3) && ((Object)item6).name.EndsWith("_attack"))
					{
						stringBuilder2.Append($"{((Object)item6).name}: aiRange={component3.m_itemData.m_shared.m_aiAttackRange:0.00} hitRange={component3.m_itemData.m_shared.m_attack.m_attackRange:0.00}\n");
					}
					else if (Object.op_Implicit((Object)(object)component3) && Object.op_Implicit((Object)(object)component3.m_itemData.m_shared.m_equipStatusEffect))
					{
						string[] obj2 = new string[6]
						{
							((Object)item6).name,
							": ",
							null,
							null,
							null,
							null
						};
						Sprite obj3 = component3.m_itemData.m_shared.m_icons[0];
						obj2[2] = ((obj3 != null) ? ((Object)obj3).name : null);
						obj2[3] = " se=";
						obj2[4] = ((Object)component3.m_itemData.m_shared.m_equipStatusEffect).name;
						obj2[5] = "\n";
						stringBuilder2.Append(string.Concat(obj2));
					}
					else if (Object.op_Implicit((Object)(object)component3) && component3.m_itemData.m_shared.m_icons.Length != 0 && !((Object)item6).name.Contains("_attack"))
					{
						string name = ((Object)item6).name;
						Sprite obj4 = component3.m_itemData.m_shared.m_icons[0];
						stringBuilder2.Append(name + ": " + ((obj4 != null) ? ((Object)obj4).name : null) + "\n");
					}
				}
				Out("icons\n" + stringBuilder2);
				break;
			}
			case "wc3use":
			{
				Player localPlayer2 = Player.m_localPlayer;
				Inventory inventory = ((Humanoid)localPlayer2).GetInventory();
				ItemData val3 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == parts[1]));
				if (val3 == null)
				{
					inventory.AddItem(ZNetScene.instance.GetPrefab(parts[1]), 1);
					val3 = inventory.GetAllItems().First((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == parts[1]);
				}
				((Humanoid)localPlayer2).UseItem(inventory, val3, true);
				Out("used " + parts[1]);
				break;
			}
			case "wc3shaders":
			{
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				foreach (GameObject item7 in ZNetScene.instance.m_prefabs.Where((GameObject p) => Object.op_Implicit((Object)(object)p)))
				{
					foreach (Renderer item8 in from r in item7.GetComponentsInChildren<Renderer>(true)
						where r is ParticleSystemRenderer || r is TrailRenderer || r is LineRenderer
						select r)
					{
						foreach (Material item9 in item8.sharedMaterials.Where((Material m) => Object.op_Implicit((Object)(object)m) && Object.op_Implicit((Object)(object)m.shader)))
						{
							string key = ((Object)item9.shader).name + (item9.HasProperty("_SrcBlend") ? string.Format(" src={0} dst={1}", item9.GetFloat("_SrcBlend"), item9.GetFloat("_DstBlend")) : "");
							if (!dictionary.ContainsKey(key))
							{
								dictionary[key] = ((Object)item7).name + "/" + ((Object)item8).name + "/" + ((Object)item9).name;
							}
						}
					}
				}
				string text = string.Join(", ", new string[5] { "Legacy Shaders/Particles/Additive", "Legacy Shaders/Particles/Alpha Blended", "Particles/Standard Unlit", "Sprites/Default", "Unlit/Transparent" }.Select((string n) => n + "=" + (Object.op_Implicit((Object)(object)Shader.Find(n)) ? "yes" : "no")));
				Out("shaders\n" + string.Join("\n", dictionary.Select((KeyValuePair<string, string> kv) => kv.Key + "  <- " + kv.Value)) + "\nfind: " + text);
				break;
			}
			case "wc3item":
			{
				StringBuilder stringBuilder4 = new StringBuilder();
				foreach (GameObject item10 in ObjectDB.instance.m_items.Where((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name.IndexOf(parts[1], StringComparison.OrdinalIgnoreCase) >= 0).Take(12))
				{
					SharedData shared = item10.GetComponent<ItemDrop>().m_itemData.m_shared;
					Attack attack = shared.m_attack;
					stringBuilder4.Append(string.Format("{0}: type={1} skill={2} atk={3} anim={4} proj={5} ", ((Object)item10).name, shared.m_itemType, shared.m_skillType, attack.m_attackType, attack.m_attackAnimation, Object.op_Implicit((Object)(object)attack.m_attackProjectile) ? ((Object)attack.m_attackProjectile).name : "-") + string.Format("n={0} vel={1} acc={2} spawnOnTrigger={3} ", attack.m_projectiles, attack.m_projectileVel, attack.m_projectileAccuracy, Object.op_Implicit((Object)(object)attack.m_spawnOnTrigger) ? ((Object)attack.m_spawnOnTrigger).name : "-") + $"eitr={attack.m_attackEitr} hp%={attack.m_attackHealthPercentage} st={attack.m_attackStamina} aiRange={shared.m_aiAttackRange} aiMin={shared.m_aiAttackRangeMin} dmg={((DamageTypes)(ref shared.m_damages)).GetTotalDamage()}\n");
					foreach (GameObject item11 in ((IEnumerable<GameObject>)(object)new GameObject[2] { attack.m_attackProjectile, attack.m_spawnOnTrigger }).Where((GameObject g) => Object.op_Implicit((Object)(object)g)))
					{
						stringBuilder4.Append("   " + ((Object)item11).name + ": " + string.Join(",", from c in item11.GetComponents<Component>()
							select ((object)c).GetType().Name) + " children=" + string.Join(",", from Transform t in (IEnumerable)item11.transform
							select ((Object)t).name) + "\n");
						Projectile component8 = item11.GetComponent<Projectile>();
						if (Object.op_Implicit((Object)(object)component8))
						{
							stringBuilder4.Append(string.Format("   projectile spawnOnHit={0} ttl={1} grav={2} aoe={3} hitFx={4}\n", Object.op_Implicit((Object)(object)component8.m_spawnOnHit) ? ((Object)component8.m_spawnOnHit).name : "-", component8.m_ttl, component8.m_gravity, component8.m_aoe, component8.m_hitEffects.m_effectPrefabs.Length));
						}
						if (Object.op_Implicit((Object)(object)component8) && Object.op_Implicit((Object)(object)component8.m_spawnOnHit))
						{
							stringBuilder4.Append("   spawnOnHit comps: " + string.Join(",", from c in component8.m_spawnOnHit.GetComponents<Component>()
								select ((object)c).GetType().Name) + "\n");
						}
					}
				}
				Out("items\n" + stringBuilder4);
				break;
			}
			case "wc3comp":
			{
				GameObject val21 = ZNetScene.instance.GetPrefab(parts[1]) ?? ObjectDB.instance.GetItemPrefab(parts[1]) ?? ObjectDB.instance.m_items.Select((GameObject i) => (!Object.op_Implicit((Object)(object)i)) ? null : i.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_attack.m_attackProjectile).FirstOrDefault((Func<GameObject, bool>)((GameObject g) => Object.op_Implicit((Object)(object)g) && ((Object)g).name == parts[1]));
				Component val22 = (Object.op_Implicit((Object)(object)val21) ? val21.GetComponent(parts[2]) : null);
				if (!Object.op_Implicit((Object)(object)val22))
				{
					Out("wc3comp: not found");
					break;
				}
				StringBuilder stringBuilder5 = new StringBuilder();
				FieldInfo[] fields = ((object)val22).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
				foreach (FieldInfo fieldInfo in fields)
				{
					object value3 = fieldInfo.GetValue(val22);
					Object val23 = (Object)((value3 is Object) ? value3 : null);
					string text2 = ((val23 != null) ? (Object.op_Implicit(val23) ? val23.name : "null") : ((value3 is IEnumerable source && !(value3 is string)) ? ("[" + string.Join(",", source.Cast<object>().Take(6).Select(delegate(object x)
					{
						Object val25 = (Object)((x is Object) ? x : null);
						if (val25 == null)
						{
							return x?.ToString();
						}
						return (!Object.op_Implicit(val25)) ? "null" : val25.name;
					})) + "]") : value3?.ToString()));
					stringBuilder5.Append(fieldInfo.FieldType.Name + " " + fieldInfo.Name + " = " + text2 + "\n");
				}
				Out($"{parts[1]}.{parts[2]}\n{stringBuilder5}");
				break;
			}
			case "wc3fx":
			{
				Player localPlayer9 = Player.m_localPlayer;
				float scale = ((parts.Length > 2) ? float.Parse(parts[2], CultureInfo.InvariantCulture) : 2f);
				float num11 = ((parts.Length > 3) ? float.Parse(parts[3], CultureInfo.InvariantCulture) : 6f);
				bool loop = parts.Contains("loop");
				val9 = Vector3.ProjectOnPlane(((Character)localPlayer9).GetLookDir(), Vector3.up);
				Vector3 normalized2 = ((Vector3)(ref val9)).normalized;
				Vector3 val14 = ((Component)localPlayer9).transform.position + normalized2 * num11;
				val14.y = ZoneSystem.instance.GetGroundHeight(val14);
				GameObject val15 = Fx.Prefab(parts[1], scale, loop);
				if (!Object.op_Implicit((Object)(object)val15))
				{
					Out("wc3fx: unknown " + parts[1] + "; have: " + string.Join(" ", Fx.Names));
					break;
				}
				GameObject val16 = Object.Instantiate<GameObject>(val15, val14, Quaternion.LookRotation(-normalized2));
				((Object)val16).name = "WC3FX_TEST";
				Out($"fx {parts[1]} at {val14}: {val16.GetComponentsInChildren<ParticleSystem>().Length} emitters, {val16.GetComponentsInChildren<Renderer>().Length} renderers");
				break;
			}
			case "wc3fxinfo":
			{
				Transform val4 = ((IEnumerable<Transform>)Object.FindObjectsByType<Transform>((FindObjectsSortMode)0)).FirstOrDefault((Func<Transform, bool>)((Transform x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == "WC3FX_TEST"));
				if (!Object.op_Implicit((Object)(object)val4))
				{
					Out("no fx");
					break;
				}
				StringBuilder stringBuilder = new StringBuilder();
				Renderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Renderer>();
				foreach (Renderer val5 in componentsInChildren)
				{
					object[] obj = new object[4]
					{
						((object)val5).GetType().Name,
						((Object)val5).name,
						val5.enabled && ((Component)val5).gameObject.activeInHierarchy,
						null
					};
					Bounds bounds = val5.bounds;
					obj[3] = ((Bounds)(ref bounds)).size;
					stringBuilder.Append(string.Format("{0} {1} on={2} size={3} mats=", obj));
					Material[] materials = val5.materials;
					foreach (Material val6 in materials)
					{
						stringBuilder.Append("[" + ((Object)val6.shader).name.Replace("Legacy Shaders/Particles/", "") + " tex=" + (Object.op_Implicit((Object)(object)val6.mainTexture) ? ((Object)val6.mainTexture).name : "NONE") + " tint=" + (val6.HasProperty("_TintColor") ? ((object)val6.GetColor("_TintColor")/*cast due to .constrained prefix*/).ToString() : "-") + "]");
					}
					ParticleSystem component = ((Component)val5).GetComponent<ParticleSystem>();
					if (Object.op_Implicit((Object)(object)component))
					{
						object arg = component.particleCount;
						object arg2 = component.isPlaying;
						Quaternion rotation = ((Component)val5).transform.rotation;
						stringBuilder.Append($" particles={arg} playing={arg2} rot={((Quaternion)(ref rotation)).eulerAngles}");
					}
					SkinnedMeshRenderer val7 = (SkinnedMeshRenderer)(object)((val5 is SkinnedMeshRenderer) ? val5 : null);
					if (Object.op_Implicit((Object)(object)val7))
					{
						Mesh sharedMesh = val7.sharedMesh;
						stringBuilder.Append($" mesh={((sharedMesh != null) ? new int?(sharedMesh.vertexCount) : ((int?)null))} bones={val7.bones.Length}");
					}
					stringBuilder.Append("\n");
				}
				Out("fxinfo\n" + stringBuilder);
				break;
			}
			case "wc3eitr":
			{
				Player localPlayer3 = Player.m_localPlayer;
				Traverse.Create((object)localPlayer3).Method("SetMaxEitr", new Type[2]
				{
					typeof(float),
					typeof(bool)
				}, (object[])null).GetValue(new object[2] { 200f, false });
				((Character)localPlayer3).AddEitr(200f);
				Out($"eitr {localPlayer3.GetEitr():0}/{((Character)localPlayer3).GetMaxEitr():0}");
				break;
			}
			case "wc3hp":
				Out("hp: " + string.Join(", ", from c in Character.GetAllCharacters()
					where ((Object)c).name.StartsWith("WC3_")
					select string.Format("{0} {1:0}/{2:0} d={3:0}", ((Object)c).name.Replace("(Clone)", ""), c.GetHealth(), c.GetMaxHealth(), Vector3.Distance(((Component)c).transform.position, ((Component)Player.m_localPlayer).transform.position))));
				break;
			case "wc3spells":
			{
				IEnumerable<string> values2 = from v in Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0)
					where Object.op_Implicit((Object)(object)v) && (((Object)v).name.StartsWith("SB_") || ((Object)v).name.StartsWith("PS_"))
					group v by ((Object)v).name.Replace("(Clone)", "") into g
					select $"{g.Key} x{g.Count()}";
				IEnumerable<string> values3 = from c in Character.GetAllCharacters()
					where ((Object)c).name.StartsWith("WC3_")
					group c by ((Object)c).name.Replace("(Clone)", "") into g
					select $"{g.Key} x{g.Count()}";
				Out("spells: " + string.Join(", ", values2) + " | creatures: " + string.Join(", ", values3));
				break;
			}
			case "wc3dmg":
				DamageLog.Enable();
				if (parts.Length > 1 && parts[1] == "clear")
				{
					DamageLog.Entries.Clear();
					Out("dmg log cleared");
				}
				else if (parts.Length > 1 && parts[1] == "detail")
				{
					Out("dmg detail\n" + DamageLog.Detail((parts.Length > 2) ? int.Parse(parts[2]) : 30));
				}
				else
				{
					Out("dmg\n" + DamageLog.Summary());
				}
				break;
			case "wc3recipe":
			{
				Recipe val20 = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe x) => Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)x.m_item) && ((Object)x.m_item).name == parts[1]));
				if (!Object.op_Implicit((Object)(object)val20))
				{
					Out("no recipe for " + parts[1]);
					break;
				}
				Out(string.Format("{0} @ {1} lvl {2}, max quality {3}: ", parts[1], Object.op_Implicit((Object)(object)val20.m_craftingStation) ? ((Object)val20.m_craftingStation).name : "hand", val20.m_minStationLevel, val20.m_item.m_itemData.m_shared.m_maxQuality) + string.Join(", ", val20.m_resources.Select(delegate(Requirement q)
				{
					ItemDrop resItem = q.m_resItem;
					return $"{((resItem != null) ? ((Object)resItem).name : null)} {q.m_amount} (+{q.m_amountPerLevel}/lvl)";
				})));
				break;
			}
			case "wc3fxclear":
				foreach (GameObject item12 in (from t in Object.FindObjectsByType<Transform>((FindObjectsSortMode)0)
					where Object.op_Implicit((Object)(object)t) && ((Object)t).name == "WC3FX_TEST"
					select ((Component)t).gameObject).ToList())
				{
					Object.Destroy((Object)(object)item12);
				}
				Out("fx cleared");
				break;
			case "wc3se":
				Out("status: " + string.Join(", ", from e in ((Character)Player.m_localPlayer).GetSEMan().GetStatusEffects()
					select ((Object)e).name) + " | equipped: " + string.Join(", ", ((Humanoid)Player.m_localPlayer).GetInventory().GetEquippedItems().Select(delegate(ItemData i)
				{
					GameObject dropPrefab = i.m_dropPrefab;
					return ((dropPrefab != null) ? ((Object)dropPrefab).name : null) + "/" + ((object)Unsafe.As<ItemType, ItemType>(ref i.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString();
				})));
				break;
			case "wc3lairs":
			{
				Player pl2 = Player.m_localPlayer;
				StringBuilder stringBuilder3 = new StringBuilder();
				int num8 = 0;
				foreach (LairDef lair in Defs.Lairs)
				{
					List<ZDO> list = new List<ZDO>();
					int num9 = 0;
					while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(lair.Id, list, ref num9))
					{
					}
					num8 += list.Count;
					ZDO val10 = list.OrderBy((ZDO z) => Vector3.Distance(z.GetPosition(), ((Component)pl2).transform.position)).FirstOrDefault();
					stringBuilder3.Append($"{lair.Id}: {list.Count}" + ((val10 != null) ? $" nearest {val10.GetPosition()} ({Vector3.Distance(val10.GetPosition(), ((Component)pl2).transform.position):0} m)" : "") + "\n");
				}
				Out($"lairs {num8}\n{stringBuilder3}");
				break;
			}
			case "wc3hit":
			{
				Player pl = Player.m_localPlayer;
				Destructible val = (from x in Object.FindObjectsByType<Destructible>((FindObjectsSortMode)0)
					where ((Object)x).name.StartsWith("WC3_Lair")
					orderby Vector3.Distance(((Component)x).transform.position, ((Component)pl).transform.position)
					select x).FirstOrDefault();
				if (!Object.op_Implicit((Object)(object)val))
				{
					Out("wc3hit: no lair");
					break;
				}
				HitData val2 = new HitData
				{
					m_point = ((Component)val).transform.position + Vector3.up,
					m_dir = Vector3.forward,
					m_toolTier = 10
				};
				val2.m_damage.m_blunt = ((parts.Length > 1) ? float.Parse(parts[1]) : 100f);
				val2.SetAttacker((Character)(object)pl);
				val.Damage(val2);
				ZDO zDO = ((Component)val).GetComponent<ZNetView>().GetZDO();
				float num = ((zDO != null) ? zDO.GetFloat(ZDOVars.s_health, val.m_health) : (-1f));
				Out($"hit {((Object)val).name} for {val2.m_damage.m_blunt}: hp {num:0}/{val.m_health:0}");
				break;
			}
			default:
				if (Object.op_Implicit((Object)(object)Console.instance))
				{
					((Terminal)Console.instance).TryRunCommand(line, false, true);
				}
				else
				{
					Out("console not ready");
				}
				break;
			}
		}

		private void State(float radius)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			Player p = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)p))
			{
				Out("state: no local player");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"player {((Component)p).transform.position} hp {((Character)p).GetHealth():0}/{((Character)p).GetMaxHealth():0}\n");
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter == (Object)(object)p)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)allCharacter).transform.position, ((Component)p).transform.position);
				if (num > radius)
				{
					continue;
				}
				Animator componentInChildren = ((Component)allCharacter).GetComponentInChildren<Animator>();
				string arg = "-";
				if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.runtimeAnimatorController))
				{
					AnimatorClipInfo[] currentAnimatorClipInfo = componentInChildren.GetCurrentAnimatorClipInfo(0);
					arg = ((currentAnimatorClipInfo.Length != 0) ? string.Join("+", currentAnimatorClipInfo.Select((AnimatorClipInfo x) => $"{((Object)((AnimatorClipInfo)(ref x)).clip).name}:{((AnimatorClipInfo)(ref x)).weight:0.0}")) : "?");
				}
				MonsterAI component = ((Component)allCharacter).GetComponent<MonsterAI>();
				string text = string.Format("  {0} d={1:0.0} hp={2:0}/{3:0} ", ((Object)allCharacter).name.Replace("(Clone)", ""), num, allCharacter.GetHealth(), allCharacter.GetMaxHealth());
				string text2 = string.Format("lvl={0} anim=[{1}] target={2} ", allCharacter.GetLevel(), arg, (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)((BaseAI)component).GetTargetCreature())) ? ((Object)((BaseAI)component).GetTargetCreature()).name : "-");
				Vector3 velocity = allCharacter.GetVelocity();
				stringBuilder.Append(text + text2 + $"vel={((Vector3)(ref velocity)).magnitude:0.0}\n");
			}
			WC3Corpse[] array = Object.FindObjectsByType<WC3Corpse>((FindObjectsSortMode)0);
			foreach (WC3Corpse wC3Corpse in array)
			{
				stringBuilder.Append(string.Format("  corpse {0} d={1:0.0}\n", ((Object)wC3Corpse).name.Replace("(Clone)", ""), Vector3.Distance(((Component)wC3Corpse).transform.position, ((Component)p).transform.position)));
			}
			IEnumerable<string> values = from i in Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0)
				where Vector3.Distance(((Component)i).transform.position, ((Component)p).transform.position) < radius
				group i by i.m_itemData.m_shared.m_name into g
				select $"{g.Key} x{g.Sum((ItemDrop i) => i.m_itemData.m_stack)}";
			stringBuilder.Append("  drops: " + string.Join(", ", values) + "\n");
			Out("state\n" + stringBuilder);
		}
	}
	public class FxDef
	{
		public string name;

		public string seq;

		public float duration;

		public bool loop;

		public bool model;

		public Dictionary<string, FxMat> materials = new Dictionary<string, FxMat>();

		public List<FxEmitter> emitters = new List<FxEmitter>();

		public List<FxRibbon> ribbons = new List<FxRibbon>();

		public List<string> sounds = new List<string>();
	}
	public class FxMat
	{
		public int filter;

		public float[][] alpha;

		public float @static = 1f;
	}
	public class FxEmitter
	{
		public string node;

		public float speed;

		public float variation;

		public float latitude;

		public float gravity;

		public float lifespan;

		public float rate;

		public float width;

		public float length;

		public float tailLength;

		public float time;

		public int filter;

		public int rows;

		public int cols;

		public int headOrTail;

		public int tex;

		public int squirt;

		public int flags;

		public float[][] colors;

		public int[] alphas;

		public float[] scaling;

		public int[] headLife;

		public int[] headDecay;

		public int[] tailLife;

		public int[] tailDecay;

		public float[] pos;

		public float[] axisX;

		public float[] axisY;

		public float[] axisZ;

		public float[][] rateCurve;

		public float[][] visCurve;

		public float[][] bursts;
	}
	public class FxRibbon
	{
		public string node;

		public float above;

		public float below;

		public float alpha;

		public float lifespan;

		public float rate;

		public float gravity;

		public float[] color;

		public float[] pos;

		public int tex;

		public int filter;

		public int rows;

		public int cols;

		public float[][] visCurve;

		public float[][] alphaCurve;
	}
	public static class Fx
	{
		private const float S = 0.01f;

		private static AssetBundle _bundle;

		private static readonly Dictionary<string, FxDef> Defs = new Dictionary<string, FxDef>();

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

		private static GameObject _holder;

		private static Shader _add;

		private static Shader _blend;

		private static GameObject _sfxTemplate;

		public static IEnumerable<string> Names => Defs.Keys;

		public static void Init(AssetBundle bundle)
		{
			_bundle = bundle;
			foreach (TextAsset item in from t in bundle.LoadAllAssets<TextAsset>()
				where ((Object)t).name.EndsWith("_fx")
				select t)
			{
				try
				{
					FxDef fxDef = JsonConvert.DeserializeObject<FxDef>(item.text);
					Defs[fxDef.name] = fxDef;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("fx " + ((Object)item).name + ": " + ex.Message));
				}
			}
			Plugin.Log.LogInfo((object)$"fx: {Defs.Count} effects");
		}

		public static FxDef Def(string name)
		{
			if (!Defs.TryGetValue(name, out var value))
			{
				return null;
			}
			return value;
		}

		private static void Shaders()
		{
			if (Object.op_Implicit((Object)(object)_add) && Object.op_Implicit((Object)(object)_blend))
			{
				return;
			}
			Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
			foreach (Shader val in array)
			{
				if (!Object.op_Implicit((Object)(object)_add) && ((Object)val).name == "Legacy Shaders/Particles/Additive")
				{
					_add = val;
				}
				if (!Object.op_Implicit((Object)(object)_blend) && ((Object)val).name == "Legacy Shaders/Particles/Alpha Blended")
				{
					_blend = val;
				}
			}
			if (Object.op_Implicit((Object)(object)_add) && Object.op_Implicit((Object)(object)_blend))
			{
				return;
			}
			foreach (GameObject item in from n in new string[3] { "ancientbarkspear_projectile", "Acorn", "staff_fireball_projectile" }
				select PrefabManager.Instance.GetPrefab(n) into p
				where Object.op_Implicit((Object)(object)p)
				select p)
			{
				Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					foreach (Material item2 in componentsInChildren[i].sharedMaterials.Where((Material m) => Object.op_Implicit((Object)(object)m) && Object.op_Implicit((Object)(object)m.shader)))
					{
						if (!Object.op_Implicit((Object)(object)_add) && ((Object)item2.shader).name == "Legacy Shaders/Particles/Additive")
						{
							_add = item2.shader;
						}
						if (!Object.op_Implicit((Object)(object)_blend) && ((Object)item2.shader).name == "Legacy Shaders/Particles/Alpha Blended")
						{
							_blend = item2.shader;
						}
						if (Object.op_Implicit((Object)(object)_add) && Object.op_Implicit((Object)(object)_blend))
						{
							return;
						}
					}
				}
			}
			Plugin.Log.LogWarning((object)$"fx shaders: additive={Object.op_Implicit((Object)(object)_add)} blend={Object.op_Implicit((Object)(object)_blend)}");
		}

		private static bool Additive(int filter)
		{
			if (filter != 1)
			{
				return filter == 4;
			}
			return true;
		}

		private static bool AdditiveLayer(int filter)
		{
			if (filter != 3)
			{
				return filter == 4;
			}
			return true;
		}

		private static Material Mat(Texture tex, bool additive)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(additive ? _add : _blend)
			{
				mainTexture = tex
			};
			if (val.HasProperty("_TintColor"))
			{
				val.SetColor("_TintColor", new Color(0.5f, 0.5f, 0.5f, 0.5f));
			}
			val.renderQueue = 3100;
			return val;
		}

		private static Texture2D Tex(string name)
		{
			Texture2D obj = _bundle.LoadAsset<Texture2D>(name);
			if (!Object.op_Implicit((Object)(object)obj))
			{
				Plugin.Log.LogWarning((object)("fx texture missing: " + name));
			}
			return obj;
		}

		public static GameObject Prefab(string name, float scale = 1f, bool loop = false, bool sound = true)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Expected O, but got Unknown
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			string text = string.Format("{0}@{1:0.###}{2}{3}", name, scale, loop ? "L" : "", sound ? "" : "q");
			if (Cache.TryGetValue(text, out var value))
			{
				return value;
			}
			FxDef fxDef = Def(name);
			if (fxDef == null)
			{
				Plugin.Log.LogError((object)("fx " + name + ": unknown"));
				return null;
			}
			Shaders();
			if (!Object.op_Implicit((Object)(object)_holder))
			{
				_holder = new GameObject("WC3FxPrefabs");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
			}
			GameObject val = new GameObject("wc3fx_" + text);
			val.transform.SetParent(_holder.transform, false);
			bool flag = loop || fxDef.loop;
			float num = 0f;
			if (fxDef.model)
			{
				GameObject val2 = _bundle.LoadAsset<GameObject>("wc3fxm_" + name);
				if (Object.op_Implicit((Object)(object)val2))
				{
					GameObject obj = Object.Instantiate<GameObject>(val2, val.transform, false);
					((Object)obj).name = "model";
					obj.transform.localScale = Vector3.one * scale;
					Animator component = obj.GetComponent<Animator>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.cullingMode = (AnimatorCullingMode)0;
					}
					WC3FxAnim wC3FxAnim = val.AddComponent<WC3FxAnim>();
					wC3FxAnim.duration = Mathf.Max(0.05f, fxDef.duration);
					wC3FxAnim.loop = flag;
					Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val3 in componentsInChildren)
					{
						Material[] sharedMaterials = val3.sharedMaterials;
						for (int j = 0; j < sharedMaterials.Length; j++)
						{
							string text2 = (Object.op_Implicit((Object)(object)sharedMaterials[j]) ? ((Object)sharedMaterials[j]).name.Split(new char[1] { ' ' })[0].Split(new char[1] { '.' })[0] : "mat0");
							fxDef.materials.TryGetValue(text2, out var value2);
							Texture2D tex = Tex(name + "_" + text2);
							sharedMaterials[j] = Mat((Texture)(object)tex, value2 != null && AdditiveLayer(value2.filter));
							wC3FxAnim.slots.Add(new WC3FxAnim.Slot
							{
								renderer = val3,
								index = j,
								alpha = Curve(value2?.alpha, value2?.@static ?? 1f),
								shown = (value2 == null || value2.@static > 0.001f || value2.alpha != null)
							});
						}
						val3.sharedMaterials = sharedMaterials;
						val3.shadowCastingMode = (ShadowCastingMode)0;
					}
				}
			}
			foreach (FxEmitter emitter in fxDef.emitters)
			{
				GameObject val4 = new GameObject("pe_" + emitter.node);
				val4.transform.SetParent(val.transform, false);
				val4.transform.localPosition = V(emitter.pos) * scale;
				num = Mathf.Max(num, emitter.lifespan);
				BuildEmitter(val4, emitter, fxDef, name, scale, flag);
			}
			Color val6 = default(Color);
			foreach (FxRibbon ribbon in fxDef.ribbons)
			{
				GameObject val5 = new GameObject("rb_" + ribbon.node);
				val5.transform.SetParent(val.transform, false);
				val5.transform.localPosition = V(ribbon.pos) * scale;
				TrailRenderer obj2 = val5.AddComponent<TrailRenderer>();
				obj2.time = Mathf.Max(0.05f, ribbon.lifespan);
				obj2.widthMultiplier = Mathf.Max(0.02f, (ribbon.above + ribbon.below) * 0.01f * scale);
				obj2.minVertexDistance = 0.05f * scale;
				((Color)(ref val6))..ctor(ribbon.color[0], ribbon.color[1], ribbon.color[2], ribbon.alpha);
				obj2.startColor = val6;
				obj2.endColor = new Color(val6.r, val6.g, val6.b, 0f);
				((Renderer)obj2).material = Mat((Texture)(object)Tex($"{name}_tex{ribbon.tex}"), AdditiveLayer(ribbon.filter) || ribbon.filter == 3);
				((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0;
				num = Mathf.Max(num, ribbon.lifespan);
			}
			if (fxDef.ribbons.Count > 0)
			{
				val.AddComponent<WC3FxTrails>();
			}
			if (sound && fxDef.sounds.Count > 0)
			{
				GameObject val7 = Sfx(name);
				if (Object.op_Implicit((Object)(object)val7))
				{
					((Object)Object.Instantiate<GameObject>(val7, val.transform, false)).name = "sfx";
				}
			}
			if (!flag)
			{
				val.AddComponent<WC3FxLife>().life = fxDef.duration + num + 0.3f;
			}
			Cache[text] = val;
			return val;
		}

		public static GameObject Sfx(string name)
		{
			FxDef fxDef = Def(name);
			if (fxDef == null || fxDef.sounds.Count == 0)
			{
				return null;
			}
			string text = "sfx_wc3fx_" + name;
			GameObject prefab = PrefabManager.Instance.GetPrefab(text);
			if (Object.op_Implicit((Object)(object)prefab))
			{
				return prefab;
			}
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("sfx_greydwarf_elite_alerted");
			if (!Object.op_Implicit((Object)(object)prefab2))
			{
				return null;
			}
			GameObject obj = PrefabManager.Instance.CreateClonedPrefab(text, prefab2);
			ZSFX component = obj.GetComponent<ZSFX>();
			component.m_audioClips = (from s in fxDef.sounds
				select _bundle.LoadAsset<AudioClip>(s) into a
				where Object.op_Implicit((Object)(object)a)
				select a).ToArray();
			component.m_minPitch = 0.97f;
			component.m_maxPitch = 1.03f;
			component.m_minVol = (component.m_maxVol = 1f);
			return obj;
		}

		private static Vector3 V(float[] a)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (a != null)
			{
				return new Vector3(a[0], a[1], a[2]);
			}
			return Vector3.zero;
		}

		private static AnimationCurve Curve(float[][] pts, float fallback)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (pts == null || pts.Length == 0)
			{
				return AnimationCurve.Constant(0f, 1f, fallback);
			}
			AnimationCurve val = new AnimationCurve();
			foreach (float[] array in pts)
			{
				val.AddKey(new Keyframe(array[0], array[1]));
			}
			for (int j = 0; j < val.length; j++)
			{
				val.SmoothTangents(j, 0f);
			}
			return val;
		}

		private static void BuildEmitter(GameObject go, FxEmitter e, FxDef d, string name, float scale, bool looping)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Expected O, but got Unknown
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Expected O, but got Unknown
			//IL_06d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Unknown result type (might be due to