Decompiled source of ConfigurableWeaponData v1.4.4

ConfigurableWeaponData.dll

Decompiled 3 days 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.Text;
using BepInEx;
using BepInEx.Configuration;
using DM;
using HarmonyLib;
using Landfall.TABS;
using Landfall.TABS.UnitEditor;
using Landfall.TABS.Workshop;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[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("ConfigurableWeaponData")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ConfigurableWeaponData")]
[assembly: AssemblyTitle("ConfigurableWeaponData")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ConfigurableWeaponData
{
	public static class EditorState
	{
		[Serializable]
		public class StoreDto
		{
			public Dictionary<string, Dictionary<string, float>> Weapons;

			public Dictionary<string, int> Summons;
		}

		public static readonly Dictionary<string, Dictionary<string, float>> Pending = new Dictionary<string, Dictionary<string, float>>();

		public static bool SuppressRemoveClear;

		public static readonly Dictionary<string, int> Summons = new Dictionary<string, int>();

		private static readonly Dictionary<int, StoreDto> BattleCache = new Dictionary<int, StoreDto>();

		public static int GetSummon(string key)
		{
			if (!Summons.TryGetValue(key, out var value))
			{
				return 0;
			}
			return value;
		}

		public static void SetSummon(string key, int guid)
		{
			if (guid == 0)
			{
				Summons.Remove(key);
			}
			else
			{
				Summons[key] = guid;
			}
		}

		public static UnitBlueprint ResolveBlueprint(int guid)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (guid == 0)
			{
				return null;
			}
			try
			{
				DatabaseID val = default(DatabaseID);
				((DatabaseID)(ref val))..ctor(guid);
				UnitBlueprint val2 = ContentDatabase.Instance().GetUnitBlueprint(val);
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ContentDatabase.Instance().GetUserUnitBlueprintByExactName(guid.ToString());
				}
				return val2;
			}
			catch
			{
				return null;
			}
		}

		public static UnitBlueprint ResolveLiveOrSaved(int guid)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
				if ((Object)(object)val != (Object)null)
				{
					object? obj = typeof(UnitEditorManager).GetField("loadedUnit", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
					UnitBlueprint val2 = (UnitBlueprint)((obj is UnitBlueprint) ? obj : null);
					if ((Object)(object)val2 != (Object)null && val2.Entity != null && val2.Entity.GUID.m_ID == guid)
					{
						object? obj2 = typeof(UnitEditorManager).GetMethod("GetBlueprint", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(val, null);
						UnitBlueprint val3 = (UnitBlueprint)((obj2 is UnitBlueprint) ? obj2 : null);
						if ((Object)(object)val3 != (Object)null)
						{
							return val3;
						}
					}
				}
			}
			catch
			{
			}
			return ResolveBlueprint(guid);
		}

		public static string ResolveUnitName(int guid)
		{
			UnitBlueprint val = ResolveBlueprint(guid);
			if ((Object)(object)val == (Object)null)
			{
				return guid.ToString();
			}
			try
			{
				if (val.Entity != null && !string.IsNullOrEmpty(val.Entity.Name))
				{
					return val.Entity.Name;
				}
			}
			catch
			{
			}
			return ((Object)val).name;
		}

		public static string KeyFor(bool right, int weaponGuid)
		{
			return (right ? "Right" : "Left") + "/" + weaponGuid;
		}

		public static bool TryGet(string key, string paramKey, out float value)
		{
			value = 0f;
			if (Pending.TryGetValue(key, out var value2))
			{
				return value2.TryGetValue(paramKey, out value);
			}
			return false;
		}

		public static void Set(string key, string paramKey, float value)
		{
			if (!Pending.TryGetValue(key, out var value2))
			{
				value2 = new Dictionary<string, float>();
				Pending[key] = value2;
			}
			value2[paramKey] = value;
			Debug.Log((object)$"[CWD] Pending[{key}][{paramKey}] = {value} (count={Pending.Count})");
		}

		public static void ClearForKey(string key)
		{
			if (Pending.Remove(key))
			{
				Debug.Log((object)$"[CWD] Pending removed {key} (count={Pending.Count})");
			}
		}

		public static void ClearAll()
		{
			if (Pending.Count > 0)
			{
				Debug.LogWarning((object)("[CWD] Pending CLEARED!\n" + Environment.StackTrace));
			}
			Pending.Clear();
		}

		public static void LoadFromJson(int unitGuid)
		{
			ClearAll();
			Summons.Clear();
			StoreDto storeDto = ReadJson(unitGuid);
			if (storeDto == null)
			{
				return;
			}
			if (storeDto.Weapons != null)
			{
				foreach (KeyValuePair<string, Dictionary<string, float>> weapon in storeDto.Weapons)
				{
					Pending[weapon.Key] = weapon.Value;
				}
			}
			if (storeDto.Summons != null)
			{
				foreach (KeyValuePair<string, int> summon in storeDto.Summons)
				{
					Summons[summon.Key] = summon.Value;
				}
			}
			Debug.Log((object)$"[CWD] Loaded {Pending.Count} weapons, {Summons.Count} summons from json for unit {unitGuid}");
		}

		public static void SaveToJson(int unitGuid)
		{
			string path = PathFor(unitGuid);
			try
			{
				Directory.CreateDirectory(Plugin.StoreDir);
				string text = JsonConvert.SerializeObject((object)new StoreDto
				{
					Weapons = Pending,
					Summons = Summons
				}, (Formatting)1);
				File.WriteAllText(path, text);
				Debug.Log((object)("[CWD] Wrote " + text.Replace("\n", " ").Replace("\r", " ")));
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] Save failed: " + ex.Message));
			}
		}

		public static void DeleteJson(int unitGuid)
		{
			try
			{
				string path = PathFor(unitGuid);
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				DropBattleCache(unitGuid);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] Delete failed: " + ex.Message));
			}
		}

		public static void PruneDefaults()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Dictionary<string, float>> item in Pending)
			{
				List<string> list2 = new List<string>();
				foreach (KeyValuePair<string, float> item2 in item.Value)
				{
					float? num = ParamRegistry.DefaultFor(item2.Key);
					if (num.HasValue && Mathf.Abs(item2.Value - num.Value) < 0.0001f)
					{
						list2.Add(item2.Key);
					}
				}
				foreach (string item3 in list2)
				{
					item.Value.Remove(item3);
				}
				if (item.Value.Count == 0)
				{
					list.Add(item.Key);
				}
			}
			foreach (string item4 in list)
			{
				Pending.Remove(item4);
			}
			if (list.Count > 0)
			{
				Debug.Log((object)$"[CWD] Pruned {list.Count} default weapons (count={Pending.Count})");
			}
		}

		public static IReadOnlyDictionary<string, float> ForBattleUnit(int unitGuid, string key)
		{
			if (unitGuid == 0)
			{
				return null;
			}
			if (!BattleCache.TryGetValue(unitGuid, out var value))
			{
				value = ReadJson(unitGuid);
				if (value == null)
				{
					value = new StoreDto();
				}
				BattleCache[unitGuid] = value;
			}
			if (value.Weapons == null || !value.Weapons.TryGetValue(key, out var value2))
			{
				return null;
			}
			return value2;
		}

		public static int ForBattleSummon(int unitGuid, string key)
		{
			if (unitGuid == 0)
			{
				return 0;
			}
			if (!BattleCache.TryGetValue(unitGuid, out var value))
			{
				value = ReadJson(unitGuid);
				if (value == null)
				{
					value = new StoreDto();
				}
				BattleCache[unitGuid] = value;
			}
			if (value.Summons == null || !value.Summons.TryGetValue(key, out var value2))
			{
				return 0;
			}
			return value2;
		}

		public static void DropBattleCache(int unitGuid)
		{
			BattleCache.Remove(unitGuid);
		}

		public static string PathFor(int unitGuid)
		{
			return Path.Combine(Plugin.StoreDir, unitGuid + ".json");
		}

		private static StoreDto ReadJson(int unitGuid)
		{
			string path = PathFor(unitGuid);
			if (!File.Exists(path))
			{
				return null;
			}
			try
			{
				string text = File.ReadAllText(path);
				StoreDto storeDto = JsonConvert.DeserializeObject<StoreDto>(text);
				if (storeDto == null)
				{
					return null;
				}
				if (storeDto.Weapons == null && storeDto.Summons == null)
				{
					Dictionary<string, Dictionary<string, float>> dictionary = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, float>>>(text);
					if (dictionary != null)
					{
						storeDto.Weapons = dictionary;
					}
				}
				return storeDto;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] Load failed: " + ex.Message));
				return null;
			}
		}
	}
	public static class ProjectileValues
	{
		private static readonly ConditionalWeakTable<RangeWeapon, Dictionary<string, float>> Table = new ConditionalWeakTable<RangeWeapon, Dictionary<string, float>>();

		public static void Set(RangeWeapon weapon, Dictionary<string, float> values)
		{
			if (!((Object)(object)weapon == (Object)null) && values != null)
			{
				Table.Remove(weapon);
				Table.Add(weapon, values);
			}
		}

		public static Dictionary<string, float> Get(RangeWeapon weapon)
		{
			if ((Object)(object)weapon == (Object)null)
			{
				return null;
			}
			if (!Table.TryGetValue(weapon, out var value))
			{
				return null;
			}
			return value;
		}
	}
	public static class HarmonyPatches
	{
		public class CWDScaleMonitor : MonoBehaviour
		{
			private Vector3 _start;

			private float _t;

			public void Init()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				_start = ((Component)this).transform.localScale;
			}

			private void Update()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				_t += Time.deltaTime;
				if (((Component)this).transform.localScale != _start)
				{
					Debug.Log((object)$"[CWD] scale changed on '{((Object)this).name}': {_start} -> {((Component)this).transform.localScale}");
					_start = ((Component)this).transform.localScale;
				}
				if (_t > 5f)
				{
					Object.Destroy((Object)(object)this);
				}
			}
		}

		[HarmonyPatch(typeof(UnitBlueprint), "SetWeapon")]
		public static class SetWeaponPatch
		{
			private static void Postfix(UnitBlueprint __instance, Weapon __result, GameObject weaponObject, HandType handType)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Invalid comparison between Unknown and I4
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if ((Object)(object)__result == (Object)null || (Object)(object)weaponObject == (Object)null)
					{
						return;
					}
					CharacterItem component = weaponObject.GetComponent<CharacterItem>();
					if ((Object)(object)component == (Object)null || component.Entity == null)
					{
						return;
					}
					int iD = component.Entity.GUID.m_ID;
					if (iD == 0)
					{
						return;
					}
					string text = EditorState.KeyFor((int)handType == 0, iD);
					Dictionary<string, float> dictionary = null;
					int num = 0;
					UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
					if ((Object)(object)val != (Object)null)
					{
						dictionary = (EditorState.Pending.TryGetValue(text, out var value) ? value : null);
					}
					else
					{
						try
						{
							num = __instance.Entity.GUID.m_ID;
						}
						catch
						{
						}
						dictionary = EditorState.ForBattleUnit(num, text) as Dictionary<string, float>;
					}
					RangeWeapon val2 = (RangeWeapon)(object)((__result is RangeWeapon) ? __result : null);
					MeleeWeapon val3 = (MeleeWeapon)(object)((__result is MeleeWeapon) ? __result : null);
					if (dictionary != null && dictionary.Count > 0)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							WeaponApplier.ApplyWeapon((Component)(object)val2, dictionary);
						}
						else if ((Object)(object)val3 != (Object)null)
						{
							WeaponApplier.ApplyWeapon((Component)(object)val3, dictionary);
						}
						else if ((Object)(object)__result != (Object)null)
						{
							WeaponApplier.ApplyWeapon((Component)(object)__result, dictionary);
						}
						Debug.Log((object)$"[CWD] SetWeapon applied {dictionary.Count} values for {text}; scale={((Component)__result).transform.localScale}");
					}
					else if (EditorState.Pending.Count > 0)
					{
						Debug.LogWarning((object)("[CWD] SetWeapon: no values for " + text + "; pending keys: " + string.Join(", ", EditorState.Pending.Keys)));
					}
					if ((Object)(object)val2 != (Object)null)
					{
						ApplySummon(val2, text, (!((Object)(object)val != (Object)null)) ? num : 0);
					}
					if ((Object)(object)val == (Object)null)
					{
						((Component)__result).gameObject.AddComponent<CWDScaleMonitor>().Init();
					}
					if (!((Object)(object)val2 != (Object)null))
					{
						return;
					}
					Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
					foreach (ParamDef item in ParamRegistry.For(WeaponTypeKind.Ranged, ParamTarget.Projectile))
					{
						if (dictionary.TryGetValue(item.Key, out var value2))
						{
							dictionary2[item.Key] = value2;
						}
					}
					if (dictionary2.Count > 0)
					{
						ProjectileValues.Set(val2, dictionary2);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] SetWeapon patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(RangeWeapon), "SetProjectileStats")]
		public static class SetProjectileStatsPatch
		{
			private static bool Prefix(RangeWeapon __instance, GameObject spawnedObject)
			{
				try
				{
					if ((Object)(object)spawnedObject != (Object)null && (Object)(object)spawnedObject.GetComponent<Unit>() != (Object)null)
					{
						return false;
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] SetProjectileStats prefix: " + ex.Message));
				}
				return true;
			}

			private static void Postfix(RangeWeapon __instance, GameObject spawnedObject)
			{
				try
				{
					if (!((Object)(object)spawnedObject == (Object)null) && !((Object)(object)spawnedObject.GetComponent<Unit>() != (Object)null))
					{
						Dictionary<string, float> dictionary = ProjectileValues.Get(__instance);
						if (dictionary != null)
						{
							WeaponApplier.ApplyProjectile(spawnedObject, dictionary);
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] SetProjectileStats patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(CustomUnitHandler), "SaveUnit")]
		public static class SaveUnitPatch
		{
			private static void Postfix(UnitBlueprint unitBlueprint)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!((Object)(object)unitBlueprint == (Object)null) && unitBlueprint.Entity != null)
					{
						DatabaseID gUID = unitBlueprint.Entity.GUID;
						if (!((DatabaseID)(ref gUID)).IsDefaultID())
						{
							EditorState.PruneDefaults();
							EditorState.SaveToJson(gUID.m_ID);
							EditorState.DropBattleCache(gUID.m_ID);
							Debug.Log((object)$"[CWD] SaveUnit postfix: persisted {EditorState.Pending.Count} weapons for guid {gUID.m_ID}");
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] SaveUnit patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(ContentDatabase), "RemoveUserUnitBlueprintAndEmptyFactionsCreated")]
		public static class RemoveUnitPatch
		{
			private static void Postfix(DatabaseID id)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!((DatabaseID)(ref id)).IsDefaultID())
					{
						EditorState.DeleteJson(id.m_ID);
						Debug.Log((object)$"[CWD] Removed weapon data for deleted unit {id.m_ID}");
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] RemoveUnit patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorManager), "LoadUnit")]
		public static class LoadUnitPatch
		{
			private static void Postfix(UnitEditorManager __instance, UnitBlueprint blueprint)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!((Object)(object)blueprint == (Object)null) && blueprint.Entity != null)
					{
						int iD = blueprint.Entity.GUID.m_ID;
						EditorState.LoadFromJson(iD);
						EditorState.DropBattleCache(iD);
						EditorState.SaveToJson(iD);
						if ((Object)(object)__instance != (Object)null && !UnitEditorManager.isTestingUnit)
						{
							__instance.RespawnWeapons();
						}
						Debug.Log((object)$"[CWD] LoadUnit: loaded + auto-saved + respawned for {iD} (entries={EditorState.Pending.Count})");
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] LoadUnit patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorManager), "RespawnWeapons")]
		public static class RespawnWeaponsPatch
		{
			private static void Prefix()
			{
				EditorState.SuppressRemoveClear = true;
			}

			private static void Postfix()
			{
				EditorState.SuppressRemoveClear = false;
			}
		}

		[HarmonyPatch(typeof(UnitEditorManager), "RemoveWeapon", new Type[] { typeof(EquipedWeaponWrapper) })]
		public static class RemoveWeaponPatch
		{
			private static void Postfix(EquipedWeaponWrapper weapon)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (weapon == null || EditorState.SuppressRemoveClear)
					{
						return;
					}
					int num = 0;
					try
					{
						CharacterItem prop = ((EquipedWrapper)weapon).prop;
						if ((Object)(object)prop != (Object)null && prop.Entity != null)
						{
							num = prop.Entity.GUID.m_ID;
						}
					}
					catch
					{
					}
					if (num != 0)
					{
						EditorState.ClearForKey(EditorState.KeyFor(weapon.isRightHanded, num));
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] RemoveWeapon patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorStatCell), "UpdateValue")]
		public static class StatCellUpdatePatch
		{
			private static void Postfix(UnitEditorStatCell __instance)
			{
				try
				{
					object? obj = typeof(UnitEditorStatCell).GetField("stat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
					StatsWrapper val = (StatsWrapper)((obj is StatsWrapper) ? obj : null);
					if (val != null && UIPatcher.IsOurs(val))
					{
						UIPatcher.OnValueEdited(val, __instance);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] StatCellUpdate patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorEquipedClothing), "Setup")]
		public static class EquipedClothingSetupPatch
		{
			private static void Postfix(UnitEditorEquipedClothing __instance, EquipedWrapper equiped)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Invalid comparison between Unknown and I4
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				try
				{
					if (equiped != null && (int)equiped.GetWrapperType() == 1)
					{
						UIPatcher.HandleWeaponPage(__instance, (EquipedWeaponWrapper)equiped);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] EquipedClothing.Setup patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorManager), "SetRider", new Type[] { typeof(UnitBlueprint) })]
		public static class SetRiderPatch
		{
			private static bool Prefix(UnitEditorManager __instance, UnitBlueprint m_unit)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!UIPatcher.SummonPickMode)
					{
						return true;
					}
					UIPatcher.SummonPickMode = false;
					if ((Object)(object)m_unit == (Object)null)
					{
						return false;
					}
					int guid = 0;
					try
					{
						guid = m_unit.Entity.GUID.m_ID;
					}
					catch
					{
					}
					UIPatcher.OnSummonPicked(__instance, guid);
					return false;
				}
				catch (Exception ex)
				{
					UIPatcher.SummonPickMode = false;
					Debug.LogWarning((object)("[CWD] SetRider patch: " + ex.Message));
					return true;
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorManager), "EquipProjectile")]
		public static class EquipProjectilePatch
		{
			private static void Postfix(ProjectileEntity projectileEntity, bool isMainHand)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if ((Object)(object)projectileEntity == (Object)null)
					{
						return;
					}
					EquipedWeaponWrapper val = UIPatcher.LastWeapon();
					if (val != null && val.isRightHanded == isMainHand)
					{
						int num = 0;
						try
						{
							num = ((EquipedWrapper)val).prop.Entity.GUID.m_ID;
						}
						catch
						{
						}
						if (num != 0)
						{
							EditorState.SetSummon(EditorState.KeyFor(isMainHand, num), 0);
							Debug.Log((object)"[CWD] projectile picked, summon cleared");
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] EquipProjectile patch: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorListSelectScreen), "Back")]
		public static class ListBackPatch
		{
			private static void Postfix()
			{
				if (UIPatcher.SummonPickMode)
				{
					UIPatcher.SummonPickMode = false;
					Debug.Log((object)"[CWD] summon picker cancelled");
				}
			}
		}

		[HarmonyPatch(typeof(UnitEditorSubMenu), "Open")]
		public static class SubMenuOpenPatch
		{
			private static void Postfix(UnitEditorSubMenu __instance)
			{
				try
				{
					UnitEditorEquipedClothing componentInParent = ((Component)__instance).GetComponentInParent<UnitEditorEquipedClothing>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						EquipedWeaponWrapper val = UIPatcher.LastWeapon();
						if (val != null && !((Object)(object)((EquipedWrapper)val).prop == (Object)null))
						{
							UIPatcher.RefreshPage(componentInParent, val);
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] SubMenuOpen patch: " + ex.Message));
				}
			}
		}

		public static void Apply()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			new Harmony("com.configurable.weapondata").PatchAll();
			Debug.Log((object)"[CWD] Harmony patches applied (SetWeapon covers editor + battle)");
		}

		public static void ApplySummon(RangeWeapon rw, string key, int battleUnitGuid)
		{
			try
			{
				int num = ((battleUnitGuid != 0) ? EditorState.ForBattleSummon(battleUnitGuid, key) : EditorState.GetSummon(key));
				if (num != 0)
				{
					UnitBlueprint val = ((battleUnitGuid != 0) ? EditorState.ResolveBlueprint(num) : EditorState.ResolveLiveOrSaved(num));
					if ((Object)(object)val == (Object)null)
					{
						Debug.LogWarning((object)$"[CWD] summon blueprint not found: {num}");
						return;
					}
					rw.unitToSpawn = val;
					rw.ObjectToSpawn = null;
					Debug.Log((object)$"[CWD] weapon {key} summons unit {num}");
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] summon apply: " + ex.Message));
			}
		}
	}
	public enum WeaponTypeKind
	{
		Ranged,
		Melee
	}
	public enum ParamTarget
	{
		Weapon,
		Projectile
	}
	public enum ComponentKind
	{
		Weapon,
		RangeWeapon,
		MeleeWeapon,
		MoveTransform,
		Collision,
		Compensation,
		Scale
	}
	public class ParamDef
	{
		public string Key;

		public string DisplayName;

		public string Description;

		public WeaponTypeKind Kind;

		public ParamTarget Target;

		public ComponentKind On;

		public string FieldName;

		public float Min;

		public float Max;

		public float Default;

		public bool IsMultiplier;

		public bool IsInt;

		public int Axis = -1;

		public FieldInfo Field;
	}
	public static class ParamRegistry
	{
		public static readonly List<ParamDef> All = new List<ParamDef>();

		private static void Add(ParamDef p)
		{
			All.Add(p);
		}

		public static void Init(ConfigFile cfg)
		{
			Add(new ParamDef
			{
				Key = "Range",
				DisplayName = "Range",
				Description = "Max attack range (m).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "maxRange",
				Min = 0.1f,
				Max = 200f,
				Default = 10f
			});
			Add(new ParamDef
			{
				Key = "MaxAngle",
				DisplayName = "Attack Angle",
				Description = "Max firing angle (deg).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "maxAngle",
				Min = 0.1f,
				Max = 360f,
				Default = 360f
			});
			Add(new ParamDef
			{
				Key = "Cooldown",
				DisplayName = "Cooldown",
				Description = "Time between attacks (s).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "internalCooldown",
				Min = 0.05f,
				Max = 20f,
				Default = 1f
			});
			Add(new ParamDef
			{
				Key = "MinRandom",
				DisplayName = "Random Min",
				Description = "Random cooldown lower bound (multiplier).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "minRandom",
				Min = 0.01f,
				Max = 5f,
				Default = 0.8f,
				IsMultiplier = true
			});
			Add(new ParamDef
			{
				Key = "MaxRandom",
				DisplayName = "Random Max",
				Description = "Random cooldown upper bound (multiplier).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "maxRandom",
				Min = 0.01f,
				Max = 5f,
				Default = 1.2f,
				IsMultiplier = true
			});
			Add(new ParamDef
			{
				Key = "Spread",
				DisplayName = "Spread",
				Description = "Inaccuracy (deg).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "spread",
				Min = 0f,
				Max = 90f,
				Default = 0f
			});
			Add(new ParamDef
			{
				Key = "Reload",
				DisplayName = "Reload Time",
				Description = "Reload duration (s).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "reloadTime",
				Min = 0f,
				Max = 60f,
				Default = 0f
			});
			Add(new ParamDef
			{
				Key = "ProjCount",
				DisplayName = "Proj Count",
				Description = "Projectiles fired per shot.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "numberOfObjects",
				Min = 1f,
				Max = 30f,
				Default = 1f,
				IsInt = true
			});
			Add(new ParamDef
			{
				Key = "MagSize",
				DisplayName = "Mag Size",
				Description = "Shots before reload.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "magSize",
				Min = 1f,
				Max = 100f,
				Default = 1f,
				IsInt = true
			});
			Add(new ParamDef
			{
				Key = "FireForce",
				DisplayName = "Proj Force",
				Description = "Launch force applied to the projectile.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "force",
				Min = 0f,
				Max = 5000f,
				Default = 1000f
			});
			Add(new ParamDef
			{
				Key = "DelayPerSpawn",
				DisplayName = "Multi-shot Delay",
				Description = "Delay between each projectile in a burst (s).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "delayPerSpawn",
				Min = 0f,
				Max = 5f,
				Default = 0.02f
			});
			Add(new ParamDef
			{
				Key = "Recoil",
				DisplayName = "Recoil",
				Description = "Weapon recoil impulse.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "shootRecoil",
				Min = 0f,
				Max = 100f,
				Default = 5f
			});
			Add(new ParamDef
			{
				Key = "TorsoRecoil",
				DisplayName = "Torso Recoil",
				Description = "Recoil applied to the torso.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Weapon,
				On = ComponentKind.RangeWeapon,
				FieldName = "torsoRecoil",
				Min = 0f,
				Max = 100f,
				Default = 5f
			});
			AddScale(WeaponTypeKind.Ranged, ParamTarget.Weapon, "Size", "Weapon size multiplier (X/Y/Z axes).");
			Add(new ParamDef
			{
				Key = "ProjDamage",
				DisplayName = "Proj Damage",
				Description = "Projectile impact damage.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.Collision,
				FieldName = "damage",
				Min = 0f,
				Max = 10000f,
				Default = 80f
			});
			Add(new ParamDef
			{
				Key = "ProjImpact",
				DisplayName = "Proj Impact",
				Description = "Projectile impact force multiplier.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.Collision,
				FieldName = "impactMultiplier",
				Min = 0f,
				Max = 20f,
				Default = 1f,
				IsMultiplier = true
			});
			Add(new ParamDef
			{
				Key = "ProjTeamDmg",
				DisplayName = "Proj Team Damage",
				Description = "Damage dealt to friendly units (fraction).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.Collision,
				FieldName = "teamDamage",
				Min = 0f,
				Max = 1f,
				Default = 0.1f
			});
			Add(new ParamDef
			{
				Key = "ProjSpeed",
				DisplayName = "Proj Speed",
				Description = "Projectile launch speed (m/s).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.MoveTransform,
				FieldName = "selfImpulse.z",
				Min = 0f,
				Max = 500f,
				Default = 30f
			});
			Add(new ParamDef
			{
				Key = "ProjGravity",
				DisplayName = "Proj Gravity",
				Description = "Projectile gravity (m/s^2).",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.MoveTransform,
				FieldName = "gravity",
				Min = 0f,
				Max = 100f,
				Default = 15f
			});
			Add(new ParamDef
			{
				Key = "ProjDrag",
				DisplayName = "Proj Drag",
				Description = "Projectile air drag.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.MoveTransform,
				FieldName = "drag",
				Min = 0f,
				Max = 10f,
				Default = 0f
			});
			Add(new ParamDef
			{
				Key = "ProjVelSpread",
				DisplayName = "Proj Vel Spread",
				Description = "Random projectile speed variance.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.MoveTransform,
				FieldName = "randomVelocitySpread",
				Min = 0f,
				Max = 50f,
				Default = 0f
			});
			Add(new ParamDef
			{
				Key = "ProjAim",
				DisplayName = "Proj Aim Assist",
				Description = "Projectile homing strength toward the target.",
				Kind = WeaponTypeKind.Ranged,
				Target = ParamTarget.Projectile,
				On = ComponentKind.Compensation,
				FieldName = "forwardCompensation",
				Min = 0f,
				Max = 5f,
				Default = 0f
			});
			AddScale(WeaponTypeKind.Ranged, ParamTarget.Projectile, "ProjSize", "Projectile size multiplier (X/Y/Z axes).");
			Add(new ParamDef
			{
				Key = "MeleeRange",
				DisplayName = "Range",
				Description = "Max melee range (m).",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "maxRange",
				Min = 0.1f,
				Max = 50f,
				Default = 2f
			});
			Add(new ParamDef
			{
				Key = "MeleeAngle",
				DisplayName = "Swing Angle",
				Description = "Max swing angle (deg).",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "maxAngle",
				Min = 1f,
				Max = 360f,
				Default = 360f
			});
			Add(new ParamDef
			{
				Key = "MeleeCooldown",
				DisplayName = "Cooldown",
				Description = "Time between swings (s).",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Weapon,
				FieldName = "internalCooldown",
				Min = 0.05f,
				Max = 20f,
				Default = 1f
			});
			Add(new ParamDef
			{
				Key = "MeleeForce",
				DisplayName = "Curve Force",
				Description = "Swing impulse magnitude.",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.MeleeWeapon,
				FieldName = "curveForce",
				Min = 0f,
				Max = 5000f,
				Default = 100f
			});
			Add(new ParamDef
			{
				Key = "MeleeDamage",
				DisplayName = "Damage",
				Description = "Melee hit damage.",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Collision,
				FieldName = "damage",
				Min = 0f,
				Max = 10000f,
				Default = 80f
			});
			Add(new ParamDef
			{
				Key = "MeleeImpact",
				DisplayName = "Impact",
				Description = "Melee impact force multiplier.",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.Collision,
				FieldName = "impactMultiplier",
				Min = 0f,
				Max = 20f,
				Default = 1f,
				IsMultiplier = true
			});
			Add(new ParamDef
			{
				Key = "ParryPower",
				DisplayName = "Parry Power",
				Description = "Force needed to parry this weapon.",
				Kind = WeaponTypeKind.Melee,
				Target = ParamTarget.Weapon,
				On = ComponentKind.MeleeWeapon,
				FieldName = "requiredPowerToParry",
				Min = 0f,
				Max = 1000f,
				Default = 100f
			});
			AddScale(WeaponTypeKind.Melee, ParamTarget.Weapon, "Size", "Weapon size multiplier (X/Y/Z axes).");
			ResolveFields();
			WriteConfigEntries(cfg);
		}

		private static void AddScale(WeaponTypeKind kind, ParamTarget target, string prefix, string desc)
		{
			Add(new ParamDef
			{
				Key = prefix + "X",
				DisplayName = prefix + " X",
				Description = desc,
				Kind = kind,
				Target = target,
				On = ComponentKind.Scale,
				Min = 0.1f,
				Max = 10f,
				Default = 1f,
				IsMultiplier = true,
				Axis = 0
			});
			Add(new ParamDef
			{
				Key = prefix + "Y",
				DisplayName = prefix + " Y",
				Description = desc,
				Kind = kind,
				Target = target,
				On = ComponentKind.Scale,
				Min = 0.1f,
				Max = 10f,
				Default = 1f,
				IsMultiplier = true,
				Axis = 1
			});
			Add(new ParamDef
			{
				Key = prefix + "Z",
				DisplayName = prefix + " Z",
				Description = desc,
				Kind = kind,
				Target = target,
				On = ComponentKind.Scale,
				Min = 0.1f,
				Max = 10f,
				Default = 1f,
				IsMultiplier = true,
				Axis = 2
			});
		}

		private static void ResolveFields()
		{
			foreach (ParamDef item in All)
			{
				if (item.On != ComponentKind.Scale)
				{
					Type type = item.On switch
					{
						ComponentKind.Weapon => typeof(Weapon), 
						ComponentKind.RangeWeapon => typeof(RangeWeapon), 
						ComponentKind.MeleeWeapon => typeof(MeleeWeapon), 
						ComponentKind.MoveTransform => typeof(MoveTransform), 
						ComponentKind.Collision => typeof(CollisionWeapon), 
						ComponentKind.Compensation => typeof(Compensation), 
						_ => null, 
					};
					if (!(type == null))
					{
						string name = (item.FieldName.Contains(".") ? item.FieldName.Split(new char[1] { '.' })[0] : item.FieldName);
						item.Field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					}
				}
			}
		}

		private static void WriteConfigEntries(ConfigFile cfg)
		{
			foreach (ParamDef item in All)
			{
				_ = cfg.Bind<float>("Parameters." + item.Kind.ToString() + "." + item.Target, item.Key, item.Default, $"Min={item.Min} Max={item.Max} Default={item.Default}. Listed params are editable in the unit editor's weapon Data tab.").Value;
			}
			cfg.Save();
		}

		public static IEnumerable<ParamDef> For(WeaponTypeKind kind)
		{
			foreach (ParamDef item in All)
			{
				if (item.Kind == kind)
				{
					yield return item;
				}
			}
		}

		public static IEnumerable<ParamDef> For(WeaponTypeKind kind, ParamTarget target)
		{
			foreach (ParamDef item in All)
			{
				if (item.Kind == kind && item.Target == target)
				{
					yield return item;
				}
			}
		}

		public static float? DefaultFor(string key)
		{
			foreach (ParamDef item in All)
			{
				if (item.Key == key)
				{
					return item.Default;
				}
			}
			return null;
		}

		public static float ReadActual(Component weaponRoot, ParamDef p, GameObject projectileOverride = null)
		{
			try
			{
				if (p.On == ComponentKind.Scale)
				{
					return 1f;
				}
				if (p.Field == null)
				{
					return p.Default;
				}
				Component val3;
				if (p.Target == ParamTarget.Projectile)
				{
					GameObject val = projectileOverride;
					if ((Object)(object)val == (Object)null)
					{
						RangeWeapon val2 = (RangeWeapon)(((object)((weaponRoot is RangeWeapon) ? weaponRoot : null)) ?? ((object)weaponRoot.GetComponent<RangeWeapon>()));
						val = (((Object)(object)val2 != (Object)null) ? val2.ObjectToSpawn : null);
					}
					if ((Object)(object)val == (Object)null)
					{
						return p.Default;
					}
					val3 = val.GetComponentInChildren(p.Field.DeclaringType);
				}
				else
				{
					val3 = ResolveOnWeapon(weaponRoot, p.On);
				}
				if ((Object)(object)val3 == (Object)null)
				{
					return p.Default;
				}
				object value = p.Field.GetValue(val3);
				if (value is float result)
				{
					return result;
				}
				if (p.IsInt && value is int num)
				{
					return num;
				}
				return p.Default;
			}
			catch
			{
				return p.Default;
			}
		}

		private static Component ResolveOnWeapon(Component weapon, ComponentKind on)
		{
			return (Component)(on switch
			{
				ComponentKind.Weapon => weapon.GetComponent<Weapon>(), 
				ComponentKind.RangeWeapon => weapon.GetComponent<RangeWeapon>(), 
				ComponentKind.MeleeWeapon => weapon.GetComponent<MeleeWeapon>(), 
				ComponentKind.Collision => weapon.GetComponentInChildren<CollisionWeapon>(), 
				ComponentKind.Compensation => weapon.GetComponentInChildren<Compensation>(), 
				_ => null, 
			});
		}
	}
	[BepInPlugin("com.configurable.weapondata", "ConfigurableWeaponData", "1.4.4")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.configurable.weapondata";

		public const string NAME = "ConfigurableWeaponData";

		public const string VERSION = "1.4.4";

		public static Plugin Instance;

		public static ConfigFile Cfg;

		public static string StoreDir;

		public void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Instance = this;
			Cfg = new ConfigFile(Path.Combine(Paths.ConfigPath, "configurableweapondata.cfg"), false);
			ParamRegistry.Init(Cfg);
			StoreDir = Path.Combine(Paths.PluginPath, "ConfigurableWeaponData", "weapons");
			Directory.CreateDirectory(StoreDir);
			HarmonyPatches.Apply();
			((BaseUnityPlugin)this).Logger.LogMessage((object)("ConfigurableWeaponData 1.4.4 loaded. Store: " + StoreDir));
		}
	}
	public static class UIPatcher
	{
		public class CWDInputRow : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
		{
			public string rowKey;

			public ParamDef param;

			public TextMeshProUGUI valueText;

			public TMP_InputField inputField;

			private Coroutine _debounce;

			private string _pending;

			private float _lastApplied = float.NaN;

			public void SetInitialApplied(float v)
			{
				_lastApplied = v;
			}

			public void OnPointerDown(PointerEventData eventData)
			{
				try
				{
					if ((Object)(object)inputField != (Object)null)
					{
						((Selectable)inputField).interactable = true;
						if ((Object)(object)EventSystem.current != (Object)null)
						{
							EventSystem.current.SetSelectedGameObject(((Component)inputField).gameObject);
						}
						inputField.ActivateInputField();
						((Selectable)inputField).Select();
						Debug.Log((object)("[CWD] Input activated on row '" + param.Key + "'"));
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] input activate: " + ex.Message));
				}
			}

			public void OnValueChanged(string newValue)
			{
				try
				{
					_pending = newValue;
					if (_debounce != null)
					{
						((MonoBehaviour)this).StopCoroutine(_debounce);
					}
					_debounce = ((MonoBehaviour)this).StartCoroutine(DebounceApply());
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] value changed: " + ex.Message));
				}
			}

			private IEnumerator DebounceApply()
			{
				yield return (object)new WaitForSeconds(0.4f);
				_debounce = null;
				ApplyText(_pending);
			}

			public void OnEndEdit(string newValue)
			{
				try
				{
					if (_debounce != null)
					{
						((MonoBehaviour)this).StopCoroutine(_debounce);
						_debounce = null;
					}
					ApplyText(newValue);
					if (float.TryParse((newValue != null) ? newValue.Trim().TrimEnd('x', 'X').Trim() : "", NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && (Object)(object)valueText != (Object)null)
					{
						((TMP_Text)valueText).text = Format(param, result);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[CWD] end edit: " + ex.Message));
				}
			}

			private void ApplyText(string s)
			{
				if (s == null)
				{
					return;
				}
				if (float.TryParse(s.Trim().TrimEnd('x', 'X').Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					if (float.IsNaN(_lastApplied) || !Mathf.Approximately(_lastApplied, result))
					{
						_lastApplied = result;
						EditorState.Set(rowKey, param.Key, result);
						UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
						if ((Object)(object)val != (Object)null && !UnitEditorManager.isTestingUnit)
						{
							val.RespawnWeapons();
						}
						Debug.Log((object)$"[CWD] applied {param.Key} = {result}");
					}
				}
				else
				{
					Debug.LogWarning((object)("[CWD] parse failed: '" + s + "'"));
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OnSaveClicked;

			public static UnityAction <1>__OpenSummonPicker;
		}

		private const string Tag = "[CWD]";

		private static WeaponTypeKind _kind;

		private static string _key;

		private static Component _weaponProp;

		private static GameObject _projOverride;

		private static EquipedWeaponWrapper _lastWeapon;

		private static GameObject _scroll;

		private static readonly List<GameObject> _rows = new List<GameObject>();

		public static bool SummonPickMode;

		private static Font _font;

		public static EquipedWeaponWrapper LastWeapon()
		{
			return _lastWeapon;
		}

		public static void RefreshPage(UnitEditorEquipedClothing page, EquipedWeaponWrapper weapon)
		{
			if ((Object)(object)_scroll != (Object)null)
			{
				KickEventSystem();
			}
			else
			{
				HandleWeaponPage(page, weapon);
			}
		}

		private static void KickEventSystem()
		{
			try
			{
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] eventsystem kick: " + ex.Message));
			}
		}

		public static bool IsOurs(StatsWrapper sw)
		{
			if (sw != null && sw.name != null)
			{
				return sw.name.StartsWith("[CWD]");
			}
			return false;
		}

		public static void HandleWeaponPage(UnitEditorEquipedClothing page, EquipedWeaponWrapper weapon)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			WeaponTypeKind kind;
			if ((Object)(object)((Component)((EquipedWrapper)weapon).prop).GetComponent<RangeWeapon>() != (Object)null)
			{
				kind = WeaponTypeKind.Ranged;
			}
			else
			{
				if (!((Object)(object)((Component)((EquipedWrapper)weapon).prop).GetComponent<MeleeWeapon>() != (Object)null))
				{
					return;
				}
				kind = WeaponTypeKind.Melee;
			}
			int num = 0;
			try
			{
				num = ((EquipedWrapper)weapon).prop.Entity.GUID.m_ID;
			}
			catch
			{
			}
			if (num == 0)
			{
				return;
			}
			_kind = kind;
			_key = EditorState.KeyFor(weapon.isRightHanded, num);
			_weaponProp = (Component)(object)((EquipedWrapper)weapon).prop;
			_projOverride = null;
			try
			{
				UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
				if ((Object)(object)val != (Object)null)
				{
					ProjectileEntity projectile = val.GetProjectile(weapon);
					if ((Object)(object)projectile != (Object)null)
					{
						_projOverride = ((Component)projectile).gameObject;
					}
				}
			}
			catch
			{
			}
			_lastWeapon = weapon;
			((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedInject(page));
		}

		private static IEnumerator DelayedInject(UnitEditorEquipedClothing page)
		{
			yield return null;
			yield return null;
			if ((Object)(object)page == (Object)null)
			{
				yield break;
			}
			try
			{
				Inject(page);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] Inject failed: " + ex.Message));
			}
		}

		public static void OpenSummonPicker()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
				if (!((Object)(object)val == (Object)null))
				{
					UnitEditorUIManager unitEditorUIManager = val.unitEditorUIManager;
					if (!((Object)(object)unitEditorUIManager == (Object)null))
					{
						SummonPickMode = true;
						UnitBlueprint[] array = ContentDatabase.Instance().GetUserUnitBlueprintsByIdExcluded(val.GetCurrentID()).ToArray();
						((MonoBehaviour)Plugin.Instance).StartCoroutine(unitEditorUIManager.listSelectScreen.Setup(array));
						unitEditorUIManager.NavigateToPage("VOICESELECT");
						((MonoBehaviour)Plugin.Instance).StartCoroutine(FixHeaderLater());
						Debug.Log((object)"[CWD] summon picker opened");
					}
				}
			}
			catch (Exception ex)
			{
				SummonPickMode = false;
				Debug.LogWarning((object)("[CWD] summon picker: " + ex.Message));
			}
		}

		private static IEnumerator FixHeaderLater()
		{
			yield return null;
			yield return null;
			try
			{
				if (SummonPickMode)
				{
					UnitEditorListSelectScreen val = Object.FindObjectOfType<UnitEditorListSelectScreen>();
					if ((Object)(object)val != (Object)null && (Object)(object)val.header != (Object)null)
					{
						val.header.Localized = false;
						val.header.LocaleID = "Select Summon Unit";
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] header fix: " + ex.Message));
			}
		}

		public static void OnSummonPicked(UnitEditorManager mgr, int guid)
		{
			try
			{
				EditorState.SetSummon(_key, guid);
				if (_lastWeapon != null)
				{
					try
					{
						mgr.EquipProjectile((ProjectileEntity)null, _lastWeapon.isRightHanded);
					}
					catch
					{
					}
				}
				if (!UnitEditorManager.isTestingUnit)
				{
					mgr.RespawnWeapons();
				}
				UnitEditorUIManager unitEditorUIManager = mgr.unitEditorUIManager;
				if ((Object)(object)unitEditorUIManager != (Object)null)
				{
					unitEditorUIManager.NavigateToPage("EQUIPEDCLOTHING");
					if (_lastWeapon != null)
					{
						unitEditorUIManager.SetupEquipedWeapon(_lastWeapon);
					}
				}
				Debug.Log((object)$"[CWD] summon picked: {guid}");
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] summon picked: " + ex.Message));
			}
		}

		private static void DumpDiagnostics(UnitEditorEquipedClothing page, Transform container)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine($"[CWD] EventSystem: current={(Object)(object)EventSystem.current != (Object)null}, module={(Object)(object)EventSystem.current != (Object)null && (Object)(object)EventSystem.current.currentInputModule != (Object)null}");
				Canvas componentInParent = ((Component)page).GetComponentInParent<Canvas>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					GraphicRaycaster component = ((Component)componentInParent).GetComponent<GraphicRaycaster>();
					stringBuilder.AppendLine($"[CWD] Canvas '{((Object)componentInParent).name}' raycaster={(Object)(object)component != (Object)null}, sortingOrder={componentInParent.sortingOrder}");
				}
				DumpNode(stringBuilder, ((Component)page).transform, "", 0, 6);
				Debug.Log((object)stringBuilder.ToString());
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] diagnostics: " + ex.Message));
			}
		}

		private static void DumpNode(StringBuilder sb, Transform t, string indent, int depth, int maxDepth)
		{
			if (!((Object)(object)t == (Object)null) && depth <= maxDepth)
			{
				GameObject gameObject = ((Component)t).gameObject;
				CanvasGroup component = gameObject.GetComponent<CanvasGroup>();
				Image component2 = gameObject.GetComponent<Image>();
				string text = "";
				if ((Object)(object)component != (Object)null)
				{
					text = $" [CG a={component.alpha} i={component.interactable} b={component.blocksRaycasts}]";
				}
				if ((Object)(object)component2 != (Object)null)
				{
					text += $" [Img rt={((Graphic)component2).raycastTarget}]";
				}
				sb.AppendLine($"{indent}{((Object)gameObject).name} active={gameObject.activeInHierarchy}{text}");
				for (int i = 0; i < t.childCount; i++)
				{
					DumpNode(sb, t.GetChild(i), indent + "  ", depth + 1, maxDepth);
				}
			}
		}

		private static void Inject(UnitEditorEquipedClothing page)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Expected O, but got Unknown
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			for (int num = _rows.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_rows[num] != (Object)null)
				{
					Object.Destroy((Object)(object)_rows[num]);
				}
			}
			_rows.Clear();
			if ((Object)(object)_scroll != (Object)null)
			{
				Object.Destroy((Object)(object)_scroll);
				_scroll = null;
			}
			object? value = F_ProjectileStat().GetValue(page);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			Transform val2 = null;
			if ((Object)(object)val != (Object)null)
			{
				val2 = val.transform.parent;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				object? value2 = F_TABSContentParent().GetValue(page);
				GameObject val3 = (GameObject)((value2 is GameObject) ? value2 : null);
				if ((Object)(object)val3 != (Object)null)
				{
					val2 = val3.transform;
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)page).transform;
			}
			for (int i = 0; i < val2.childCount; i++)
			{
				GameObject gameObject = ((Component)val2.GetChild(i)).gameObject;
				if (!((Object)(object)val != (Object)null) || !((Object)(object)gameObject == (Object)(object)val))
				{
					gameObject.SetActive(false);
				}
			}
			GameObject val4 = (_scroll = new GameObject("CWDScroll", new Type[5]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(ScrollRect),
				typeof(RectMask2D),
				typeof(LayoutElement)
			}));
			val4.transform.SetParent(val2, false);
			LayoutElement component = val4.GetComponent<LayoutElement>();
			component.minHeight = 300f;
			component.preferredHeight = 340f;
			component.flexibleHeight = 1f;
			Image component2 = val4.GetComponent<Image>();
			((Graphic)component2).color = new Color(0f, 0f, 0f, 0.02f);
			((Graphic)component2).raycastTarget = true;
			ScrollRect component3 = val4.GetComponent<ScrollRect>();
			GameObject val5 = new GameObject("Content", new Type[3]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup),
				typeof(ContentSizeFitter)
			});
			val5.transform.SetParent(val4.transform, false);
			VerticalLayoutGroup component4 = val5.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component4).spacing = 2f;
			((LayoutGroup)component4).padding = new RectOffset(2, 2, 2, 2);
			val5.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			RectTransform component5 = val5.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 1f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.pivot = new Vector2(0.5f, 1f);
			component3.content = component5;
			component3.viewport = val4.GetComponent<RectTransform>();
			component3.horizontal = false;
			component3.vertical = true;
			component3.movementType = (MovementType)2;
			component3.scrollSensitivity = 25f;
			component3.inertia = true;
			int num2 = 0;
			foreach (ParamDef item2 in ParamRegistry.For(_kind))
			{
				float v = item2.Default;
				if (EditorState.TryGet(_key, item2.Key, out var value3))
				{
					v = value3;
				}
				else if ((Object)(object)_weaponProp != (Object)null)
				{
					v = ParamRegistry.ReadActual(_weaponProp, item2, _projOverride);
				}
				GameObject item = MakeRow(val5.transform, item2, v);
				_rows.Add(item);
				num2++;
			}
			if (_kind == WeaponTypeKind.Ranged)
			{
				_rows.Add(MakeSummonButtonRow(val5.transform));
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(EditorState.GetSummon(_key) == 0);
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.transform.SetAsLastSibling();
			}
			_rows.Add(MakeSaveRow(val2));
			Debug.Log((object)$"[CWD] CustomRows: {num2} rows under '{((Object)val2).name}'");
			try
			{
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] eventsystem kick: " + ex.Message));
			}
			DumpDiagnostics(page, val2);
		}

		private static GameObject MakeSaveRow(Transform parent)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0066: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			Resources val = default(Resources);
			GameObject val2 = new GameObject("CWD_Save", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val2.transform.SetParent(parent, false);
			val2.transform.SetAsLastSibling();
			LayoutElement component = val2.GetComponent<LayoutElement>();
			component.minHeight = 40f;
			component.preferredHeight = 40f;
			GameObject obj = DefaultControls.CreateButton(val);
			((Object)obj).name = "SaveButton";
			obj.transform.SetParent(val2.transform, false);
			RectTransform component2 = obj.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			Button component3 = obj.GetComponent<Button>();
			Image component4 = obj.GetComponent<Image>();
			component4.sprite = null;
			((Graphic)component4).color = new Color(0.25f, 0.5f, 0.3f, 0.95f);
			Text componentInChildren = obj.GetComponentInChildren<Text>();
			componentInChildren.text = "Save Weapon Data";
			componentInChildren.font = GetFont();
			componentInChildren.fontSize = 18;
			componentInChildren.alignment = (TextAnchor)4;
			((Graphic)componentInChildren).color = Color.white;
			ButtonClickedEvent onClick = component3.onClick;
			object obj2 = <>O.<0>__OnSaveClicked;
			if (obj2 == null)
			{
				UnityAction val3 = OnSaveClicked;
				<>O.<0>__OnSaveClicked = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			return val2;
		}

		private static void OnSaveClicked()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EditorState.PruneDefaults();
				int num = 0;
				UnitEditorManager val = Object.FindObjectOfType<UnitEditorManager>();
				if ((Object)(object)val != (Object)null)
				{
					object? obj = typeof(UnitEditorManager).GetField("loadedUnit", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
					UnitBlueprint val2 = (UnitBlueprint)((obj is UnitBlueprint) ? obj : null);
					if ((Object)(object)val2 != (Object)null && val2.Entity != null)
					{
						num = val2.Entity.GUID.m_ID;
					}
				}
				if (num != 0)
				{
					EditorState.SaveToJson(num);
				}
				if ((Object)(object)val != (Object)null && !UnitEditorManager.isTestingUnit)
				{
					val.RespawnWeapons();
				}
				Debug.Log((object)$"[CWD] Weapon data saved (guid={num}, entries={EditorState.Pending.Count})");
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[CWD] save click: " + ex.Message));
			}
		}

		private static Font GetFont()
		{
			if ((Object)(object)_font == (Object)null)
			{
				_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				if ((Object)(object)_font == (Object)null)
				{
					try
					{
						_font = Font.CreateDynamicFontFromOSFont("Arial", 14);
					}
					catch
					{
						_font = null;
					}
				}
			}
			return _font;
		}

		private static GameObject MakeRow(Transform parent, ParamDef p, float v)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: 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_02bb: Unknown result type (might be due to invalid IL or missing references)
			Resources val = default(Resources);
			GameObject val2 = new GameObject("CWD_" + p.Key, new Type[3]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup),
				typeof(LayoutElement)
			});
			val2.transform.SetParent(parent, false);
			CanvasGroup obj = val2.AddComponent<CanvasGroup>();
			obj.alpha = 1f;
			obj.interactable = true;
			obj.blocksRaycasts = true;
			HorizontalLayoutGroup component = val2.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).spacing = 4f;
			((LayoutGroup)component).padding = new RectOffset(4, 4, 2, 2);
			LayoutElement component2 = val2.GetComponent<LayoutElement>();
			component2.minHeight = 32f;
			component2.preferredHeight = 32f;
			GameObject obj2 = DefaultControls.CreateText(val);
			((Object)obj2).name = "Name";
			obj2.transform.SetParent(val2.transform, false);
			Text component3 = obj2.GetComponent<Text>();
			component3.font = GetFont();
			component3.text = "          " + p.DisplayName;
			component3.fontSize = 16;
			component3.alignment = (TextAnchor)3;
			component3.horizontalOverflow = (HorizontalWrapMode)1;
			((Graphic)component3).color = new Color(0.92f, 0.92f, 0.92f, 1f);
			LayoutElement obj3 = obj2.AddComponent<LayoutElement>();
			obj3.preferredWidth = 150f;
			obj3.flexibleWidth = 1f;
			GameObject val3 = new GameObject("Value", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField)
			});
			val3.transform.SetParent(val2.transform, false);
			Image component4 = val3.GetComponent<Image>();
			component4.sprite = null;
			((Graphic)component4).raycastTarget = true;
			((Graphic)component4).color = new Color(0.22f, 0.22f, 0.28f, 0.95f);
			TMP_InputField component5 = val3.GetComponent<TMP_InputField>();
			GameObject val4 = new GameObject("Text", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val4.transform.SetParent(val3.transform, false);
			RectTransform component6 = val4.GetComponent<RectTransform>();
			component6.anchorMin = Vector2.zero;
			component6.anchorMax = Vector2.one;
			component6.offsetMin = new Vector2(8f, 0f);
			component6.offsetMax = new Vector2(-8f, 0f);
			TextMeshProUGUI component7 = val4.GetComponent<TextMeshProUGUI>();
			TMP_FontAsset currentFont = Localizer.GetCurrentFont(0);
			if ((Object)(object)currentFont != (Object)null)
			{
				((TMP_Text)component7).font = currentFont;
			}
			((TMP_Text)component7).fontSize = 16f;
			((TMP_Text)component7).alignment = (TextAlignmentOptions)513;
			((Graphic)component7).color = new Color(1f, 1f, 1f, 1f);
			((Graphic)component7).raycastTarget = false;
			component5.textComponent = (TMP_Text)(object)component7;
			((Selectable)component5).targetGraphic = (Graphic)(object)component4;
			component5.contentType = (ContentType)3;
			((Selectable)component5).interactable = true;
			component5.text = Format(p, v);
			LayoutElement obj4 = val3.AddComponent<LayoutElement>();
			obj4.preferredWidth = 110f;
			obj4.flexibleWidth = 0f;
			CWDInputRow cWDInputRow = val3.AddComponent<CWDInputRow>();
			cWDInputRow.rowKey = _key;
			cWDInputRow.param = p;
			cWDInputRow.valueText = component7;
			cWDInputRow.inputField = component5;
			cWDInputRow.SetInitialApplied(v);
			((UnityEvent<string>)(object)component5.onValueChanged).AddListener((UnityAction<string>)cWDInputRow.OnValueChanged);
			((UnityEvent<string>)(object)component5.onEndEdit).AddListener((UnityAction<string>)cWDInputRow.OnEndEdit);
			return val2;
		}

		private static GameObject MakeSummonButtonRow(Transform parent)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			Resources val = default(Resources);
			GameObject val2 = new GameObject("CWD_Summon", new Type[3]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup),
				typeof(LayoutElement)
			});
			val2.transform.SetParent(parent, false);
			CanvasGroup obj = val2.AddComponent<CanvasGroup>();
			obj.alpha = 1f;
			obj.interactable = true;
			obj.blocksRaycasts = true;
			HorizontalLayoutGroup component = val2.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).spacing = 4f;
			((LayoutGroup)component).padding = new RectOffset(4, 4, 2, 2);
			LayoutElement component2 = val2.GetComponent<LayoutElement>();
			component2.minHeight = 32f;
			component2.preferredHeight = 32f;
			GameObject obj2 = DefaultControls.CreateText(val);
			((Object)obj2).name = "Name";
			obj2.transform.SetParent(val2.transform, false);
			Text component3 = obj2.GetComponent<Text>();
			component3.font = GetFont();
			component3.text = "          Summon Unit";
			component3.fontSize = 16;
			component3.alignment = (TextAnchor)3;
			component3.horizontalOverflow = (HorizontalWrapMode)1;
			((Graphic)component3).color = new Color(0.92f, 0.92f, 0.92f, 1f);
			LayoutElement obj3 = obj2.AddComponent<LayoutElement>();
			obj3.preferredWidth = 150f;
			obj3.flexibleWidth = 1f;
			GameObject obj4 = DefaultControls.CreateButton(val);
			((Object)obj4).name = "Value";
			obj4.transform.SetParent(val2.transform, false);
			Button component4 = obj4.GetComponent<Button>();
			((Selectable)component4).interactable = true;
			Image component5 = obj4.GetComponent<Image>();
			if ((Object)(object)component5 != (Object)null)
			{
				component5.sprite = null;
				((Graphic)component5).raycastTarget = true;
				((Graphic)component5).color = new Color(0.22f, 0.22f, 0.28f, 0.95f);
			}
			Text componentInChildren = obj4.GetComponentInChildren<Text>();
			componentInChildren.font = GetFont();
			componentInChildren.fontSize = 16;
			componentInChildren.alignment = (TextAnchor)3;
			componentInChildren.horizontalOverflow = (HorizontalWrapMode)1;
			((Graphic)componentInChildren).color = new Color(1f, 1f, 1f, 1f);
			int summon = EditorState.GetSummon(_key);
			componentInChildren.text = "          " + ((summon != 0) ? EditorState.ResolveUnitName(summon) : "none (click to pick)");
			LayoutElement obj5 = obj4.AddComponent<LayoutElement>();
			obj5.preferredWidth = 200f;
			obj5.flexibleWidth = 1f;
			ButtonClickedEvent onClick = component4.onClick;
			object obj6 = <>O.<1>__OpenSummonPicker;
			if (obj6 == null)
			{
				UnityAction val3 = OpenSummonPicker;
				<>O.<1>__OpenSummonPicker = val3;
				obj6 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj6);
			return val2;
		}

		public static string Format(ParamDef p, float v)
		{
			if (!p.IsInt)
			{
				return v.ToString("F2");
			}
			return Mathf.RoundToInt(v).ToString();
		}

		public static void OnValueEdited(StatsWrapper sw, UnitEditorStatCell cell)
		{
		}

		private static FieldInfo F_ProjectileStat()
		{
			return typeof(UnitEditorEquipedClothing).GetField("ProjectileStat", BindingFlags.Instance | BindingFlags.NonPublic);
		}

		private static FieldInfo F_TABSContentParent()
		{
			return typeof(UnitEditorEquipedClothing).GetField("TABSContentParent", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}
	public static class WeaponApplier
	{
		public class CWDScaleHolder : MonoBehaviour
		{
			public Vector3 baseScale;
		}

		public static void ApplyWeapon(Component weapon, IReadOnlyDictionary<string, float> values)
		{
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)weapon == (Object)null || values == null || values.Count == 0)
			{
				return;
			}
			bool kind = !(weapon is RangeWeapon);
			GameObject gameObject = weapon.gameObject;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(1f, 1f, 1f);
			bool flag = false;
			foreach (ParamDef item in ParamRegistry.For(kind ? WeaponTypeKind.Melee : WeaponTypeKind.Ranged, ParamTarget.Weapon))
			{
				if (!values.TryGetValue(item.Key, out var value))
				{
					continue;
				}
				if (item.On == ComponentKind.Scale)
				{
					if (item.Axis >= 0 && item.Axis <= 2)
					{
						int axis = item.Axis;
						((Vector3)(ref val))[axis] = ((Vector3)(ref val))[axis] * value;
						flag = true;
					}
				}
				else
				{
					if (item.Field == null)
					{
						continue;
					}
					try
					{
						Component val2 = Resolve(weapon, item.On);
						if (!((Object)(object)val2 == (Object)null))
						{
							if (item.FieldName.Contains("."))
							{
								SetVectorComponent(val2, item.FieldName, value);
							}
							else if (item.IsInt)
							{
								item.Field.SetValue(val2, (int)Mathf.Round(value));
							}
							else
							{
								item.Field.SetValue(val2, value);
							}
						}
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[CWD] apply " + item.Key + ": " + ex.Message));
					}
				}
			}
			if (flag)
			{
				CWDScaleHolder cWDScaleHolder = gameObject.GetComponent<CWDScaleHolder>();
				if ((Object)(object)cWDScaleHolder == (Object)null)
				{
					cWDScaleHolder = gameObject.AddComponent<CWDScaleHolder>();
					cWDScaleHolder.baseScale = gameObject.transform.localScale;
				}
				gameObject.transform.localScale = new Vector3(cWDScaleHolder.baseScale.x * val.x, cWDScaleHolder.baseScale.y * val.y, cWDScaleHolder.baseScale.z * val.z);
			}
		}

		public static void ApplyProjectile(GameObject spawned, IReadOnlyDictionary<string, float> values)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)spawned == (Object)null || values == null || values.Count == 0)
			{
				return;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(1f, 1f, 1f);
			bool flag = false;
			foreach (ParamDef item in ParamRegistry.For(WeaponTypeKind.Ranged, ParamTarget.Projectile))
			{
				if (!values.TryGetValue(item.Key, out var value))
				{
					continue;
				}
				if (item.On == ComponentKind.Scale)
				{
					if (item.Axis >= 0 && item.Axis <= 2)
					{
						int axis = item.Axis;
						((Vector3)(ref val))[axis] = ((Vector3)(ref val))[axis] * value;
						flag = true;
					}
				}
				else
				{
					if (item.Field == null)
					{
						continue;
					}
					try
					{
						Component componentInChildren = spawned.GetComponentInChildren(item.Field.DeclaringType);
						if (!((Object)(object)componentInChildren == (Object)null))
						{
							if (item.FieldName.Contains("."))
							{
								SetVectorComponent(componentInChildren, item.FieldName, value);
							}
							else
							{
								item.Field.SetValue(componentInChildren, value);
							}
						}
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[CWD] apply proj " + item.Key + ": " + ex.Message));
					}
				}
			}
			if (flag)
			{
				CWDScaleHolder cWDScaleHolder = spawned.GetComponent<CWDScaleHolder>();
				if ((Object)(object)cWDScaleHolder == (Object)null)
				{
					cWDScaleHolder = spawned.AddComponent<CWDScaleHolder>();
					cWDScaleHolder.baseScale = spawned.transform.localScale;
				}
				spawned.transform.localScale = new Vector3(cWDScaleHolder.baseScale.x * val.x, cWDScaleHolder.baseScale.y * val.y, cWDScaleHolder.baseScale.z * val.z);
			}
		}

		private static Component Resolve(Component weapon, ComponentKind on)
		{
			return (Component)(on switch
			{
				ComponentKind.Weapon => weapon, 
				ComponentKind.RangeWeapon => (weapon is RangeWeapon) ? weapon : null, 
				ComponentKind.MeleeWeapon => (weapon is MeleeWeapon) ? weapon : null, 
				ComponentKind.Collision => weapon.GetComponentInChildren<CollisionWeapon>(), 
				ComponentKind.Compensation => weapon.GetComponentInChildren<Compensation>(), 
				_ => null, 
			});
		}

		private static void SetVectorComponent(Component target, string path, float v)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			string[] array = path.Split(new char[1] { '.' });
			FieldInfo field = ((object)target).GetType().GetField(array[0], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field == null))
			{
				Vector3 val = (Vector3)field.GetValue(target);
				switch (array[1])
				{
				case "x":
					val.x = v;
					break;
				case "y":
					val.y = v;
					break;
				case "z":
					val.z = v;
					break;
				}
				field.SetValue(target, val);
			}
		}
	}
}