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);
}
}
}