Decompiled source of SecondMelee v1.0.3

plugins/SecondMelee/SecondMelee.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using Gloomwood;
using Gloomwood.Entity.Items;
using Gloomwood.UI;
using HarmonyLib;
using UnityEngine;

[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("SecondMelee")]
[assembly: AssemblyVersion("1.0.2.0")]
namespace GloomwoodSecondMelee;

[BepInPlugin("local.gloomwood.dualmelee", "SecondMelee", "1.0.2")]
public sealed class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(PlayerInventory), "SaveData")]
	private static class SaveFallback
	{
		private static void Postfix(object __result)
		{
			SetSafeFallbackIndices(__result);
		}
	}

	[HarmonyPatch(typeof(PlayerInventory), "OnEntityInitialize")]
	private static class AddSecondCell
	{
		private static void Prefix(PlayerInventory __instance)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_01b0: 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_01d8: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: 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)
			//IL_01f5: 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_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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)
			FieldInfo fieldInfo = Field(typeof(PlayerInventory), "grids");
			InventoryGrid[] array = (InventoryGrid[])fieldInfo.GetValue(__instance);
			if (array == null || array.Any((InventoryGrid g) => Object.op_Implicit((Object)(object)g) && g.GridId == "grid_melee_dual"))
			{
				return;
			}
			InventoryGrid val = ((IEnumerable<InventoryGrid>)array).FirstOrDefault((Func<InventoryGrid, bool>)((InventoryGrid g) => Object.op_Implicit((Object)(object)g) && g.GridId == "grid_melee"));
			if (Object.op_Implicit((Object)(object)val))
			{
				if ((int)val.GridType != 1 || val.MaxItemCount != 1)
				{
					throw new InvalidOperationException("Unsupported melee grid; refusing to change inventory.");
				}
				InventoryGrid val2 = Object.Instantiate<InventoryGrid>(val, ((Component)val).transform.parent);
				((Object)((Component)val2).gameObject).name = "SecondMelee Second Cell";
				Field(typeof(InventoryGrid), "gridId").SetValue(val2, "grid_melee_dual");
				Field(typeof(InventoryGrid), "gridIndex").SetValue(val2, array.Length);
				InventoryCell[] componentsInChildren = ((Component)val2).GetComponentsInChildren<InventoryCell>(true);
				foreach (InventoryCell val3 in componentsInChildren)
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
				}
				FieldInfo fieldInfo2 = Field(typeof(InventoryGrid), "referenceWorldSize");
				Vector2 val4 = (Vector2)fieldInfo2.GetValue(val);
				Vector3 val5 = ((val4.x >= val4.y) ? Vector3.right : Vector3.up);
				float num2 = ((val4.x >= val4.y) ? val4.x : val4.y);
				Vector2 size = ((val4.x >= val4.y) ? new Vector2(val4.x * 0.48f, val4.y) : new Vector2(val4.x, val4.y * 0.48f));
				Vector3 localPosition = ((Component)val).transform.localPosition;
				SetCellLayout(val, localPosition - val5 * num2 * 0.25f, size);
				SetCellLayout(val2, localPosition + val5 * num2 * 0.25f, size);
				FieldInfo fieldInfo3 = Field(typeof(InventoryPanel), "grids");
				InventoryGrid[] array2 = (InventoryGrid[])fieldInfo3.GetValue(val.Panel);
				if (array2 != null)
				{
					fieldInfo3.SetValue(val.Panel, array2.Concat((IEnumerable<InventoryGrid>)(object)new InventoryGrid[1] { val2 }).ToArray());
				}
				fieldInfo.SetValue(__instance, array.Concat((IEnumerable<InventoryGrid>)(object)new InventoryGrid[1] { val2 }).ToArray());
				ConnectNavigation(val, val2);
				Log.LogInfo((object)"Created two melee cells with native item filtering and save IDs.");
			}
		}

		private static void SetCellLayout(InventoryGrid grid, Vector3 position, Vector2 size)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Field(typeof(InventoryGrid), "referenceWorldSize").SetValue(grid, size);
			((Component)grid).transform.localPosition = position;
			Field(typeof(UIWindow), "localPositionStart").SetValue(grid, position);
			((GameLoopComponent)grid).TryInitialize();
			grid.Resize(grid.GridSize);
		}

		private static void ConnectNavigation(InventoryGrid first, InventoryGrid second)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo fieldInfo = Field(typeof(InventoryGrid), "navigation");
			NavigationSettings val = (NavigationSettings)fieldInfo.GetValue(first);
			NavigationSettings val2 = new NavigationSettings();
			val2.upTargets = val.upTargets;
			val2.downTargets = val.downTargets;
			val2.leftTargets = val.leftTargets;
			val2.rightTargets = val.rightTargets;
			NavigationSettings val3 = val2;
			if (Mathf.Abs(((Component)first).transform.localPosition.x - ((Component)second).transform.localPosition.x) > 0.0001f)
			{
				val3.leftTargets = (InventoryGrid[])(object)new InventoryGrid[1] { first };
				val.rightTargets = (InventoryGrid[])(object)new InventoryGrid[1] { second };
			}
			else
			{
				val3.downTargets = (InventoryGrid[])(object)new InventoryGrid[1] { first };
				val.upTargets = (InventoryGrid[])(object)new InventoryGrid[1] { second };
			}
			fieldInfo.SetValue(second, val3);
		}
	}

	[HarmonyPatch]
	private static class PreferFreeMeleeCell
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
			Type grid = typeof(InventoryGrid).MakeByRefType();
			yield return typeof(PlayerInventory).GetMethod("TryFindGrid", flags, null, new Type[3]
			{
				typeof(InventoryItem),
				typeof(bool),
				grid
			}, null);
			yield return typeof(PlayerInventory).GetMethod("TryFindGrid", flags, null, new Type[4]
			{
				typeof(InventoryItem),
				typeof(InventoryItemEquipFlags),
				typeof(bool),
				grid
			}, null);
		}

		private static void Postfix(PlayerInventory __instance, InventoryItem item, ref InventoryGrid grid, ref bool __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			InventoryGrid val = default(InventoryGrid);
			InventoryGrid val2 = default(InventoryGrid);
			if (Object.op_Implicit((Object)(object)item) && (int)item.ItemGroup == 1 && (int)item.EquipType != 0 && __instance.TryGetGrid("grid_melee", ref val) && __instance.TryGetGrid("grid_melee_dual", ref val2) && val.AllowItem(item) && (!Object.op_Implicit((Object)(object)grid) || IsMeleeGrid(grid) || (int)grid.GridType == 2))
			{
				InventoryGrid val3 = ((val.ItemCount == 0) ? val : ((val2.ItemCount == 0) ? val2 : null));
				if (Object.op_Implicit((Object)(object)val3))
				{
					grid = val3;
					__result = true;
				}
			}
		}
	}

	public const string SecondGridId = "grid_melee_dual";

	internal static ManualLogSource Log;

	private void Awake()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		new Harmony("local.gloomwood.dualmelee").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"SecondMelee loaded. Native inventory shortcuts select each weapon independently.");
	}

	internal static FieldInfo Field(Type type, string name)
	{
		return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
	}

	internal static bool IsMeleeGrid(InventoryGrid grid)
	{
		if (Object.op_Implicit((Object)(object)grid))
		{
			if (!(grid.GridId == "grid_melee"))
			{
				return grid.GridId == "grid_melee_dual";
			}
			return true;
		}
		return false;
	}

	internal static void SetSafeFallbackIndices(object data)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		string[] array = new string[2] { "items", "shortcuts" };
		foreach (string name in array)
		{
			Array array2 = (Array)Field(data.GetType(), name).GetValue(data);
			for (int j = 0; j < array2.Length; j++)
			{
				object value = array2.GetValue(j);
				if (!((string)Field(value.GetType(), "gridId").GetValue(value) != "grid_melee_dual"))
				{
					FieldInfo fieldInfo = Field(value.GetType(), "grid");
					InventoryGridVector val = (InventoryGridVector)fieldInfo.GetValue(value);
					val.index = 0;
					fieldInfo.SetValue(value, val);
					array2.SetValue(value, j);
				}
			}
		}
	}
}