Decompiled source of RemovePlayerPlacements v1.0.0

BepInEx/plugins/RemovePlayerPlacements/RemovePlayerPlacements.dll

Decompiled 3 weeks ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameEvent;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RemovePlayerPlacements")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RemovePlayerPlacements")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d9a26543-7813-4d2e-b35f-39ec1985059a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RemovePlayerPlacements
{
	public class PieceDestroyedEventListener : IGameEventListener
	{
		void IGameEventListener.handleEvent(GameEvent e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			DestroyPieceEvent val = (DestroyPieceEvent)e;
			Placeable piece = val.Piece;
			_ = val.PlayerNetworkNumber;
			Placement placement = null;
			int num = -1;
			foreach (int key in RemovePlayerPlacementsPlugin.Instance.playerPlacements.Keys)
			{
				foreach (Placement item in RemovePlayerPlacementsPlugin.Instance.playerPlacements[key])
				{
					if (((object)item.placedObject).Equals((object?)piece))
					{
						placement = item;
						num = key;
						break;
					}
				}
				if (placement != null)
				{
					break;
				}
			}
			if (num > 0)
			{
				RemovePlayerPlacementsPlugin.Instance.playerPlacements[num].Remove(placement);
			}
		}
	}
	public class PiecePlacedEventListener : IGameEventListener
	{
		void IGameEventListener.handleEvent(GameEvent e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			PiecePlacedEvent val = (PiecePlacedEvent)e;
			Placeable placedBlock = val.PlacedBlock;
			int playerNumber = val.PlayerNumber;
			if (playerNumber != 0 && !placedBlock.Name.Equals("Bomb Mini") && !placedBlock.Name.Equals("3x3 Bomb") && !placedBlock.Name.Equals("Bomb Mega"))
			{
				LobbyPlayer lobbyPlayer = LobbyManager.instance.GetLobbyPlayer(playerNumber);
				PlayerReference playerRef = new PlayerReference(lobbyPlayer.playerName, playerNumber, lobbyPlayer.NetworkPlayerColor);
				Placement item = new Placement(placedBlock, placedBlock.ID, placedBlock.OriginalPosition, placedBlock.OriginalRotation, destroyed: false, playerRef);
				if (!RemovePlayerPlacementsPlugin.Instance.playerPlacements.ContainsKey(playerNumber))
				{
					RemovePlayerPlacementsPlugin.Instance.playerPlacements.Add(playerNumber, new List<Placement>());
				}
				RemovePlayerPlacementsPlugin.Instance.playerPlacements[playerNumber].Add(item);
			}
		}
	}
	public class Placement
	{
		public Placeable placedObject;

		public bool destroyed;

		public int id;

		public Vector2 originalPosition;

		public Quaternion originalRotation;

		public PlayerReference playerRef;

		public Placement(Placeable placedObject, int id, Vector2 originalPosition, Quaternion originalRotation, bool destroyed = false, PlayerReference playerRef = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			this.placedObject = placedObject;
			this.id = id;
			this.originalPosition = originalPosition;
			this.originalRotation = originalRotation;
			this.playerRef = playerRef;
			this.destroyed = destroyed;
		}
	}
	public class PlayerReference
	{
		public string name;

		public int playerNumber;

		public Color color;

		public PlayerReference(string name, int playerNumber, Color color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			this.name = name;
			this.playerNumber = playerNumber;
			this.color = color;
		}
	}
	[BepInPlugin("RemovePlayerPlacements", "Remove Player Placements", "1.0.0")]
	public class RemovePlayerPlacementsPlugin : BaseUnityPlugin
	{
		private class HighlightEntry
		{
			public GameObject highlightObj;

			public GameObject targetObj;
		}

		private const string modGUID = "RemovePlayerPlacements";

		private const string modName = "Remove Player Placements";

		private const string modVersion = "1.0.0";

		public Dictionary<int, List<Placement>> playerPlacements = new Dictionary<int, List<Placement>>();

		private static Harmony harmony = new Harmony("RemovePlayerPlacements");

		public static RemovePlayerPlacementsPlugin Instance;

		private bool indication;

		private List<HighlightEntry> highlightEntries = new List<HighlightEntry>();

		public GamePhase gamePhase = (GamePhase)1;

		private Character[] characters;

		private GameObject cachedNameTagPrefab;

		private int offsetIndex;

		private int lastOffsetIndex;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin loaded.");
			harmony.PatchAll();
			RemovePlayerPlacementsConfig.Bind(((BaseUnityPlugin)this).Config);
		}

		private void Start()
		{
			GameEventManager.ChangeListener<PiecePlacedEvent>((IGameEventListener)(object)new PiecePlacedEventListener(), true);
			GameEventManager.ChangeListener<DestroyPieceEvent>((IGameEventListener)(object)new PieceDestroyedEventListener(), true);
			GameEventManager.ChangeListener<StartPhaseEvent>((IGameEventListener)(object)new StartPhaseEventListener(), true);
			SceneManager.activeSceneChanged += ChangedActiveScene;
		}

		private void ChangedActiveScene(Scene current, Scene next)
		{
			playerPlacements.Clear();
			characters = null;
			cachedNameTagPrefab = null;
		}

		private void Update()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (InTreehouse() || (Object)(object)LobbyManager.instance == (Object)null || ((NetworkLobbyManager)LobbyManager.instance).lobbySlots == null || ((NetworkLobbyManager)LobbyManager.instance).lobbySlots.Length == 0 || (Object)(object)((NetworkLobbyManager)LobbyManager.instance).lobbySlots[0] == (Object)null || !LobbyManager.instance.IsHost)
			{
				return;
			}
			if (Input.GetKeyDown(RemovePlayerPlacementsConfig.PlacementSelectionKey.Value))
			{
				offsetIndex = 0;
				characters = Object.FindObjectsOfType<Character>();
			}
			if (Input.GetKey(RemovePlayerPlacementsConfig.PlacementSelectionKey.Value))
			{
				if (characters == null)
				{
					characters = Object.FindObjectsOfType<Character>();
				}
				ShowIndicator();
				int num = -1;
				for (int i = 1; i <= 9; i++)
				{
					if (Input.GetKeyDown((KeyCode)(49 + (i - 1))) || Input.GetKeyDown((KeyCode)(257 + (i - 1))))
					{
						num = i;
						break;
					}
				}
				if (num >= 0)
				{
					Rollback(num);
				}
				Scroll();
				UpdateHighlights();
			}
			else
			{
				HideIndicator();
			}
		}

		private void Scroll()
		{
			float axis = Input.GetAxis("Mouse ScrollWheel");
			if (axis == 0f)
			{
				return;
			}
			int num = ((axis < 0f) ? 1 : (-1));
			int num2 = 0;
			foreach (List<Placement> value in playerPlacements.Values)
			{
				num2 = Mathf.Max(num2, value.Count);
			}
			offsetIndex = Mathf.Clamp(offsetIndex + num, 0, Mathf.Max(0, num2 - 1));
			if (offsetIndex != lastOffsetIndex)
			{
				HideIndicator();
				ShowIndicator();
			}
			lastOffsetIndex = offsetIndex;
		}

		private void ShowIndicator()
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (indication)
			{
				return;
			}
			foreach (int key in playerPlacements.Keys)
			{
				List<Placement> list = playerPlacements[key];
				if (list.Count == 0)
				{
					continue;
				}
				int num = list.Count - 1 - offsetIndex;
				num = Mathf.Clamp(num, 0, list.Count - 1);
				Placement placement = list[num];
				if ((Object)(object)placement.placedObject != (Object)null && (Object)(object)((Component)placement.placedObject).gameObject != (Object)null)
				{
					GameObject go = ((Component)placement.placedObject).gameObject;
					if (!highlightEntries.Exists((HighlightEntry h) => (Object)(object)h.targetObj == (Object)(object)go))
					{
						Highlight(((Component)placement.placedObject).gameObject, "(" + key + ") " + placement.playerRef.name, placement.playerRef.color);
					}
				}
			}
			indication = true;
		}

		private void HideIndicator()
		{
			if (!indication)
			{
				return;
			}
			foreach (HighlightEntry highlightEntry in highlightEntries)
			{
				if ((Object)(object)highlightEntry.highlightObj != (Object)null)
				{
					Object.Destroy((Object)(object)highlightEntry.highlightObj);
				}
			}
			highlightEntries.Clear();
			indication = false;
		}

		public void Highlight(GameObject go, string hint, Color color)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			GameObject copiedNameTag = GetCopiedNameTag();
			if (!((Object)(object)copiedNameTag == (Object)null))
			{
				copiedNameTag.transform.SetParent((Transform)null);
				copiedNameTag.transform.position = go.transform.position;
				Text componentInChildren = copiedNameTag.GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.text = hint;
					((Graphic)componentInChildren).color = color;
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"NameTag does not have a UnityEngine.UI.Text component.");
				}
				highlightEntries.Add(new HighlightEntry
				{
					highlightObj = copiedNameTag,
					targetObj = go
				});
			}
		}

		private void UpdateHighlights()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!indication)
			{
				return;
			}
			for (int num = highlightEntries.Count - 1; num >= 0; num--)
			{
				HighlightEntry highlightEntry = highlightEntries[num];
				if ((Object)(object)highlightEntry.targetObj == (Object)null)
				{
					if ((Object)(object)highlightEntry.highlightObj != (Object)null)
					{
						Object.Destroy((Object)(object)highlightEntry.highlightObj);
					}
					highlightEntries.RemoveAt(num);
				}
				else if ((Object)(object)highlightEntry.highlightObj != (Object)null)
				{
					highlightEntry.highlightObj.transform.position = highlightEntry.targetObj.transform.position;
				}
			}
		}

		public GameObject GetCopiedNameTag()
		{
			if (characters == null)
			{
				return null;
			}
			Character[] array = characters;
			foreach (Character val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.AssociatedGamePlayer != (Object)null && (Object)(object)val.AssociatedGamePlayer.CursorInstance != (Object)null && (Object)(object)val.AssociatedGamePlayer.CursorInstance.nameTag != (Object)null)
				{
					cachedNameTagPrefab = ((Component)val.AssociatedGamePlayer.CursorInstance.nameTag).gameObject;
					break;
				}
			}
			if ((Object)(object)cachedNameTagPrefab == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(cachedNameTagPrefab);
			NameTag component = obj.GetComponent<NameTag>();
			if ((Object)(object)component != (Object)null)
			{
				component.currentAlpha = 1f;
				component.nameCanvasGroup.alpha = 1f;
				component.canvas.sortingOrder = 32767;
			}
			return obj;
		}

		public bool InTreehouse()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name == "TreeHouseLobby";
		}

		public Placement GetPlacementWithOffsetBy(int playerId)
		{
			if (!playerPlacements.ContainsKey(playerId))
			{
				return null;
			}
			List<Placement> list = playerPlacements[playerId];
			if (list.Count == 0)
			{
				return null;
			}
			int num = list.Count - 1 - offsetIndex;
			num = Mathf.Clamp(num, 0, list.Count - 1);
			return list[num];
		}

		public void Rollback(int playerId)
		{
			Placement placementWithOffsetBy = GetPlacementWithOffsetBy(playerId);
			if (placementWithOffsetBy != null)
			{
				if (placementWithOffsetBy.destroyed)
				{
					_ = ((NetworkManager)LobbyManager.instance).client;
				}
				else if (!((Object)(object)placementWithOffsetBy.placedObject == (Object)null) && !((Object)(object)((Component)placementWithOffsetBy.placedObject).gameObject == (Object)null))
				{
					playerPlacements[playerId].Remove(placementWithOffsetBy);
					placementWithOffsetBy.placedObject.DestroySelf(false, RemovePlayerPlacementsConfig.UseSmoke.Value, true);
					HideIndicator();
					ShowIndicator();
				}
			}
		}
	}
	internal class RemovePlayerPlacementsConfig
	{
		public static ConfigEntry<KeyCode> PlacementSelectionKey;

		public static ConfigEntry<bool> UseSmoke;

		public static void Bind(ConfigFile config)
		{
			PlacementSelectionKey = config.Bind<KeyCode>("General", "Placement Selection Key", (KeyCode)313, "Key to highlight Player Placements. While highlighting you can remove placements.");
			UseSmoke = config.Bind<bool>("General", "Use Animation", false, "Whether or not to use an animation when destroying placements");
		}
	}
	internal class StartPhaseEventListener : IGameEventListener
	{
		public void handleEvent(GameEvent e)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			if (e is StartPhaseEvent)
			{
				StartPhaseEvent val = (StartPhaseEvent)e;
				RemovePlayerPlacementsPlugin.Instance.gamePhase = val.Phase;
				if ((int)val.Phase == 1)
				{
					RemovePlayerPlacementsPlugin.Instance.playerPlacements.Clear();
				}
			}
		}
	}
}
namespace RemovePlayerPlacements.Patches
{
	[HarmonyPatch(typeof(EmoteSystem), "ReceiveEvent")]
	public class EmoteSystemPatch
	{
		private static bool Prefix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return !Input.GetKey(RemovePlayerPlacementsConfig.PlacementSelectionKey.Value);
		}
	}
}