Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MoveBuildPieces v1.0.1
MoveBuildPieces.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] namespace Obelisk.MoveBuildPieces; [BepInPlugin("obelisk.valheim.movebuildpieces", "MoveBuildPieces", "1.0.1")] public sealed class MoveBuildPiecesPlugin : BaseUnityPlugin { public const string PluginGuid = "obelisk.valheim.movebuildpieces"; public const string PluginName = "MoveBuildPieces"; public const string PluginVersion = "1.0.1"; private static ConfigEntry<bool> _enabled; private static ConfigEntry<KeyboardShortcut> _moveHotkey; private static ConfigEntry<bool> _blockTerrainModifiers; private static ConfigEntry<bool> _blockDynamicObjects; private Harmony _harmony; internal static bool IsEnabled => _enabled.Value; internal static KeyboardShortcut MoveHotkey => _moveHotkey.Value; internal static bool BlockTerrainModifiers => _blockTerrainModifiers.Value; internal static bool BlockDynamicObjects => _blockDynamicObjects.Value; private void Awake() { //IL_0037: 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_00a0: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable moving already built pieces while in build mode."); _moveHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Move hotkey", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Press while hovering a buildable player-built piece in build mode to start or cancel moving it."); _blockTerrainModifiers = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "Block terrain modifiers", true, "Do not move pieces that contain TerrainModifier or TerrainOp components."); _blockDynamicObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "Block dynamic objects", true, "Do not move ships, carts, characters, or pieces with non-kinematic rigidbodies."); MoveController.Initialize(); _harmony = new Harmony("obelisk.valheim.movebuildpieces"); _harmony.PatchAll(); } private void OnDestroy() { MoveController.Reset(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Player), "Update")] internal static class PlayerUpdatePatch { private static void Postfix(Player __instance) { MoveController.Update(__instance); } } [HarmonyPatch(typeof(Player), "LateUpdate")] internal static class PlayerLateUpdatePatch { private static void Postfix(Player __instance) { MoveController.UpdateVisuals(__instance); } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] internal static class PlayerHaveRequirementsPatch { private static bool Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) if (MoveController.ShouldBypassRequirements(__instance, piece, mode)) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] internal static class PlayerTryPlacePiecePatch { private static bool Prefix(Player __instance, Piece piece, ref bool __result) { if (!MoveController.IsMovingWith(__instance, piece)) { return true; } __result = false; MoveController.TryFinishMove(__instance); return false; } } internal static class MoveController { private sealed class MoveState { public Player Player; public Piece Piece; public ZNetView NetView; public string PrefabName; public Vector3 OriginalPosition; public Quaternion OriginalRotation; public List<EffectArea> OriginalBaseAreas; public GameObject HighlightedGhost; public bool GhostHighlighted; } private sealed class MoveSelectionOverride { public Player Player; public string PrefabName; } private static class SupportCollidersBuffer { public static readonly Collider[] Items = (Collider[])(object)new Collider[128]; } private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost"); private static readonly FieldInfo PlacementStatusField = AccessTools.Field(typeof(Player), "m_placementStatus"); private static readonly MethodInfo SetupPlacementGhostMethod = AccessTools.Method(typeof(Player), "SetupPlacementGhost", (Type[])null, (Type[])null); private static readonly MethodInfo UpdateAvailablePiecesListMethod = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static readonly MethodInfo ClearCachedSupportMethod = AccessTools.Method(typeof(WearNTear), "RPC_ClearCachedSupport", (Type[])null, (Type[])null); private static readonly Color GhostColor = new Color(0.22f, 0.66f, 1f, 0.75f); private static readonly Color GhostEmissionColor = new Color(0.05f, 0.42f, 0.9f, 0.9f); private static readonly Color LinkColor = new Color(1f, 0.9f, 0.2f, 0.92f); private static readonly Color RingColor = new Color(1f, 0.95f, 0.35f, 0.9f); private const int RingSegments = 28; private const float LinkWidth = 0.075f; private const float DashLength = 0.35f; private const float MinRingRadius = 0.6f; private const float MaxRingRadius = 8f; private const float RingPadding = 0.25f; private const float TopLinkPadding = 0.15f; private const float DefaultLinkHeight = 1.25f; private const float MinUsefulBoundsSize = 0.05f; private static readonly List<Collider> SupportColliders = new List<Collider>(); private static readonly HashSet<WearNTear> SupportPieces = new HashSet<WearNTear>(); private static readonly RaycastHit[] FloorHits = (RaycastHit[])(object)new RaycastHit[16]; private static MoveState _state; private static MoveSelectionOverride _selectionOverride; private static GameObject _lineObject; private static LineRenderer _dashLine; private static LineRenderer _originRing; private static LineRenderer _ghostRing; private static Texture2D _dashTexture; private static int _floorMask; public static void Initialize() { Reset(); } public static void Reset() { _state = null; DestroyLine(); } public static void Update(Player player) { //IL_0035: 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) if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } if (ShouldCancelForUiOrState(player)) { Cancel(player, showMessage: false); return; } if (!IsUiBlockingInput()) { KeyboardShortcut moveHotkey = MoveBuildPiecesPlugin.MoveHotkey; if (((KeyboardShortcut)(ref moveHotkey)).IsDown()) { if (_state != null) { Cancel(player, showMessage: true); } else { StartMove(player); } } } if (_state != null) { UpdateMoveGhostValidity(player); } } public static void UpdateVisuals(Player player) { if (MoveBuildPiecesPlugin.IsEnabled && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && _state != null) { UpdateLineAndGhost(player); } } public static bool IsMovingWith(Player player, Piece selectedPiece) { if (_state == null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player || (Object)(object)selectedPiece == (Object)null) { return false; } return Utils.GetPrefabName(((Component)selectedPiece).gameObject) == _state.PrefabName; } public static bool ShouldBypassRequirements(Player player, Piece piece, RequirementMode mode) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } if ((int)mode != 0 && (int)mode != 2) { return false; } string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); if (_state != null && (Object)(object)player == (Object)(object)_state.Player && prefabName == _state.PrefabName) { return CanBypassResourceRequirements(player, piece, mode); } if (_selectionOverride != null && (Object)(object)player == (Object)(object)_selectionOverride.Player && prefabName == _selectionOverride.PrefabName) { return CanBypassResourceRequirements(player, piece, mode); } return false; } public static void TryFinishMove(Player player) { //IL_003e: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (_state == null || (Object)(object)player != (Object)(object)_state.Player) { return; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost == (Object)null) { Message(player, "$msg_invalidplacement"); Cancel(player, showMessage: false); return; } if ((int)GetPlacementStatus(player) != 0) { Message(player, "$msg_invalidplacement"); return; } Vector3 position = placementGhost.transform.position; Quaternion rotation = placementGhost.transform.rotation; if (ValidateMoveDestination(player, position, showMessage: true) && ValidateMoveTarget(player, _state.Piece)) { MovePiece(_state, position, rotation); Message(player, "Moved " + Localization.instance.Localize(_state.Piece.m_name)); _state.Piece.m_placeEffect.Create(position, rotation, ((Component)_state.Piece).transform, 1f, -1); Cancel(player, showMessage: false); } } private static void StartMove(Player player) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e7: Unknown result type (might be due to invalid IL or missing references) if (!((Character)player).InPlaceMode()) { return; } Piece hoveringPiece = player.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { Message(player, "Hover a build piece to move it"); } else { if (!ValidateMoveTarget(player, hoveringPiece)) { return; } if (!SelectMovePiece(player, hoveringPiece)) { Message(player, "$msg_missingrequirement"); return; } SetupPlacementGhostMethod?.Invoke(player, Array.Empty<object>()); if ((Object)(object)GetPlacementGhost(player) == (Object)null) { Message(player, "$msg_invalidplacement"); return; } List<EffectArea> baseAreasAt = GetBaseAreasAt(((Component)hoveringPiece).transform.position); if (baseAreasAt.Count == 0) { Message(player, "Only pieces inside a base territory can be moved"); return; } _state = new MoveState { Player = player, Piece = hoveringPiece, NetView = ((Component)hoveringPiece).GetComponent<ZNetView>(), PrefabName = Utils.GetPrefabName(((Component)hoveringPiece).gameObject), OriginalPosition = ((Component)hoveringPiece).transform.position, OriginalRotation = ((Component)hoveringPiece).transform.rotation, OriginalBaseAreas = baseAreasAt }; Message(player, "Move mode: place the ghost to move " + Localization.instance.Localize(hoveringPiece.m_name)); UpdateMoveGhostValidity(player); } } private static bool SelectMovePiece(Player player, Piece piece) { _selectionOverride = new MoveSelectionOverride { Player = player, PrefabName = Utils.GetPrefabName(((Component)piece).gameObject) }; try { UpdateAvailablePiecesListMethod?.Invoke(player, Array.Empty<object>()); return player.SetSelectedPiece(piece); } finally { _selectionOverride = null; } } private static bool ValidateMoveTarget(Player player, Piece piece) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || (Object)(object)player == (Object)null) { return false; } if (!piece.m_canBeRemoved || !piece.IsPlacedByPlayer()) { Message(player, "Only player-built removable pieces can be moved"); return false; } if (Location.IsInsideNoBuildLocation(((Component)piece).transform.position)) { Message(player, "$msg_nobuildzone"); return false; } if (!PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false)) { Message(player, "$msg_privatezone"); return false; } if (!IsInsideBaseTerritory(((Component)piece).transform.position)) { Message(player, "Only pieces inside a base territory can be moved"); return false; } ZNetView component = ((Component)piece).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Message(player, "$msg_invalidplacement"); return false; } if (!piece.CanBeRemoved()) { Message(player, "$msg_cantremovenow"); return false; } if (MoveBuildPiecesPlugin.BlockTerrainModifiers && HasTerrainMutation(piece)) { Message(player, "Pieces that modify terrain are blocked"); return false; } if (MoveBuildPiecesPlugin.BlockDynamicObjects && HasBlockedDynamicComponent(piece)) { Message(player, "Dynamic pieces are blocked"); return false; } if (IsContainerInUse(piece)) { Message(player, "$msg_inuse"); return false; } return true; } private static bool HasTerrainMutation(Piece piece) { if (!((Object)(object)((Component)piece).GetComponentInChildren<TerrainModifier>(true) != (Object)null)) { return (Object)(object)((Component)piece).GetComponentInChildren<TerrainOp>(true) != (Object)null; } return true; } private static bool HasBlockedDynamicComponent(Piece piece) { if ((Object)(object)((Component)piece).GetComponentInChildren<Ship>(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren<Vagon>(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren<Character>(true) != (Object)null) { return true; } Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val in componentsInChildren) { if ((Object)(object)val != (Object)null && !val.isKinematic) { return true; } } return false; } private static bool IsContainerInUse(Piece piece) { Container[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Container>(true); foreach (Container val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.IsInUse()) { return true; } } return false; } private static bool IsInsideBaseTerritory(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return (Object)(object)EffectArea.IsPointInsideArea(point, (Type)4, 0.05f) != (Object)null; } private static bool ValidateMoveDestination(Player player, Vector3 targetPosition, bool showMessage) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (Location.IsInsideNoBuildLocation(targetPosition)) { if (showMessage) { Message(player, "$msg_nobuildzone"); } return false; } if (!PrivateArea.CheckAccess(targetPosition, 0f, true, false)) { if (showMessage) { Message(player, "$msg_privatezone"); } return false; } if (!IsInsideMoveTerritory(targetPosition)) { if (showMessage) { Message(player, "Target is outside the original base territory"); } return false; } if ((Object)(object)_state?.Piece != (Object)null && !HasRequiredBuildStationInRange(_state.Piece, ((Component)player).transform.position)) { if (showMessage) { Message(player, "$msg_missingstation"); } return false; } if ((Object)(object)_state?.Piece != (Object)null && !HasRequiredBuildStationInRange(_state.Piece, targetPosition)) { if (showMessage) { Message(player, "$msg_missingstation"); } return false; } return true; } private static bool CanBypassResourceRequirements(Player player, Piece piece, RequirementMode mode) { //IL_000c: 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) if (!player.HaveRequirements(piece, (RequirementMode)1)) { return false; } if ((int)mode == 0) { return HasRequiredBuildStationInRange(piece, ((Component)player).transform.position); } return true; } private static bool HasRequiredBuildStationInRange(Piece piece, Vector3 point) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || (Object)(object)piece.m_craftingStation == (Object)null) { return true; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)22)) { return true; } return (Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, point) != (Object)null; } private static bool IsInsideMoveTerritory(Vector3 point) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (_state?.OriginalBaseAreas == null || _state.OriginalBaseAreas.Count == 0) { return false; } foreach (EffectArea originalBaseArea in _state.OriginalBaseAreas) { if (IsPointInsideArea(originalBaseArea, point)) { return true; } } return false; } private static List<EffectArea> GetBaseAreasAt(Vector3 point) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) List<EffectArea> list = new List<EffectArea>(); foreach (EffectArea allArea in EffectArea.GetAllAreas()) { if (IsPointInsideArea(allArea, point)) { list.Add(allArea); } } return list; } private static bool IsPointInsideArea(EffectArea area, Vector3 point) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)area == (Object)null || (area.m_type & 4) == 0) { return false; } Collider component = ((Component)area).GetComponent<Collider>(); if (!((Object)(object)component == (Object)null)) { Bounds bounds = component.bounds; if (((Bounds)(ref bounds)).Contains(point)) { return Vector3.Distance(component.ClosestPoint(point), point) <= 0.1f; } } return false; } private static void MovePiece(MoveState state, Vector3 targetPosition, Quaternion targetRotation) { //IL_0016: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) ZNetView netView = state.NetView; if (!netView.IsOwner()) { netView.ClaimOwnership(); } ClearSupportCachesNear(state.OriginalPosition); ClearSupportCachesNear(targetPosition); ZDO zDO = netView.GetZDO(); zDO.SetPosition(targetPosition); zDO.SetRotation(targetRotation); ((Component)state.Piece).transform.SetPositionAndRotation(targetPosition, targetRotation); Rigidbody[] componentsInChildren = ((Component)state.Piece).GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.position = targetPosition; val.rotation = targetRotation; val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } } Physics.SyncTransforms(); ClearSupportCachesNear(targetPosition); } private static void ClearSupportCachesNear(Vector3 position) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (ClearCachedSupportMethod == null) { return; } SupportColliders.Clear(); SupportPieces.Clear(); int num = Physics.OverlapSphereNonAlloc(position, 8f, SupportCollidersBuffer.Items, LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" })); for (int i = 0; i < num; i++) { Collider val = SupportCollidersBuffer.Items[i]; WearNTear val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<WearNTear>() : null); if ((Object)(object)val2 != (Object)null && SupportPieces.Add(val2)) { ClearCachedSupportMethod.Invoke(val2, new object[1] { ZDOMan.GetSessionID() }); ZNetView component = ((Component)val2).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.InvokeRPC(ZNetView.Everybody, "RPC_ClearCachedSupport", Array.Empty<object>()); } } } } private static void UpdateMoveGhostValidity(Player player) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 GameObject placementGhost = GetPlacementGhost(player); if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null) { Cancel(player, showMessage: false); return; } bool flag = ValidateMoveDestination(player, placementGhost.transform.position, showMessage: false); Piece component = placementGhost.GetComponent<Piece>(); if (!((Object)(object)component != (Object)null)) { return; } if (flag && (int)GetPlacementStatus(player) == 0) { component.SetInvalidPlacementHeightlight(false); if ((Object)(object)_state.HighlightedGhost != (Object)(object)placementGhost || !_state.GhostHighlighted) { ApplyMoveGhostHighlight(placementGhost); _state.HighlightedGhost = placementGhost; _state.GhostHighlighted = true; } } else { component.SetInvalidPlacementHeightlight(true); _state.GhostHighlighted = false; } } private static void UpdateLineAndGhost(Player player) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) GameObject placementGhost = GetPlacementGhost(player); if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null) { Cancel(player, showMessage: false); return; } EnsureLine(); Vector3 position = ((Component)_state.Piece).transform.position; Vector3 position2 = placementGhost.transform.position; Vector3 val = ProjectToGround(position); Vector3 val2 = ProjectToGround(position2); Vector3 topLinkPoint = GetTopLinkPoint(((Component)_state.Piece).gameObject, val); Vector3 topLinkPoint2 = GetTopLinkPoint(placementGhost, val2); float ringRadius = GetRingRadius(((Component)_state.Piece).gameObject); float ringRadius2 = GetRingRadius(placementGhost); UpdateLinkObject(val, val2, topLinkPoint, topLinkPoint2, ringRadius, ringRadius2, placementGhost.activeInHierarchy); UpdateMoveGhostValidity(player); } private static void UpdateLinkObject(Vector3 groundStart, Vector3 groundEnd, Vector3 linkStart, Vector3 linkEnd, float originRingRadius, float ghostRingRadius, bool visible) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0046: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_lineObject == (Object)null) && !((Object)(object)_dashLine == (Object)null) && !((Object)(object)_originRing == (Object)null) && !((Object)(object)_ghostRing == (Object)null)) { if (!IsFinite(linkStart) || !IsFinite(linkEnd) || Vector3.Distance(linkStart, linkEnd) <= 0.05f) { linkStart = groundStart + Vector3.up * 1.25f; linkEnd = groundEnd + Vector3.up * 1.25f; } float num = Vector3.Distance(linkStart, linkEnd); bool num2 = visible && num > 0.05f; SetLineVisible(num2); if (num2) { DrawRing(_originRing, groundStart, originRingRadius); DrawRing(_ghostRing, groundEnd, ghostRingRadius); DrawDash(linkStart, linkEnd, num); } } } private static void ApplyMoveGhostHighlight(GameObject ghost) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0072: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ghost.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if (!((Object)(object)val2 == (Object)null)) { SetMaterialColor(val2, "_Color", GhostColor); SetMaterialColor(val2, "_BaseColor", GhostColor); SetMaterialColor(val2, "_TintColor", GhostColor); SetMaterialColor(val2, "_EmissionColor", GhostEmissionColor); val2.EnableKeyword("_EMISSION"); } } } } private static void SetMaterialColor(Material material, string property, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(property)) { material.SetColor(property, color); } } private static Vector3 ProjectToGround(Vector3 worldPosition) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0022: Unknown result type (might be due to invalid IL or missing references) if (TryFindFloorY(worldPosition, 4f, out var floorY)) { return new Vector3(worldPosition.x, floorY + 0.03f, worldPosition.z); } return worldPosition; } private static Vector3 GetTopLinkPoint(GameObject gameObject, Vector3 fallbackGroundPoint) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (TryGetObjectBounds(gameObject, out var bounds)) { Vector3 center = ((Bounds)(ref bounds)).center; float num = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x, num, center.z); if (IsFinite(val)) { return val; } } Piece component = gameObject.GetComponent<Piece>(); if ((Object)(object)component != (Object)null && TryGetSnapPointBounds(component, out bounds)) { Vector3 center2 = ((Bounds)(ref bounds)).center; float num2 = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(center2.x, num2, center2.z); if (IsFinite(val2)) { return val2; } } return fallbackGroundPoint + Vector3.up * 1.25f; } private static bool TryGetObjectBounds(GameObject gameObject, out Bounds bounds) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) bool hasBounds = TryCollectColliderBounds(gameObject, out bounds); if (!IsUsefulBounds(bounds, hasBounds)) { hasBounds = TryCollectRendererBounds(gameObject, out bounds); } if (!IsUsefulBounds(bounds, hasBounds)) { hasBounds = TryCollectMeshBounds(gameObject, out bounds); } return IsUsefulBounds(bounds, hasBounds); } private static float GetRingRadius(GameObject gameObject) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (TryGetObjectBounds(gameObject, out var bounds)) { float num = Mathf.Sqrt(((Bounds)(ref bounds)).extents.x * ((Bounds)(ref bounds)).extents.x + ((Bounds)(ref bounds)).extents.z * ((Bounds)(ref bounds)).extents.z); if (IsFinite(num) && num > 0f) { return Mathf.Clamp(num + 0.25f, 0.6f, 8f); } } return 0.6f; } private static bool TryCollectColliderBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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) bool hasBounds = false; bounds = default(Bounds); Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger) { AddBounds(ref bounds, ref hasBounds, val.bounds); } } return hasBounds; } private static bool TryCollectRendererBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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) bool hasBounds = false; bounds = default(Bounds); Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled && !(((object)val).GetType().Name == "ParticleSystemRenderer")) { AddBounds(ref bounds, ref hasBounds, val.bounds); } } return hasBounds; } private static bool TryCollectMeshBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) bool hasBounds = false; bounds = default(Bounds); MeshFilter[] componentsInChildren = gameObject.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null); if (!((Object)(object)val2 == (Object)null)) { Bounds bounds2 = val2.bounds; Vector3 val3 = ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center); Vector3 val4 = Vector3.Scale(((Bounds)(ref bounds2)).size, Abs(((Component)val).transform.lossyScale)); AddBounds(ref bounds, ref hasBounds, new Bounds(val3, val4)); } } return hasBounds; } private static bool TryGetSnapPointBounds(Piece piece, out Bounds bounds) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) List<Transform> list = new List<Transform>(); piece.GetSnapPoints(list); bool hasBounds = false; bounds = default(Bounds); Bounds candidate = default(Bounds); foreach (Transform item in list) { if (!((Object)(object)item == (Object)null)) { ((Bounds)(ref candidate))..ctor(item.position, Vector3.one * 0.05f); AddBounds(ref bounds, ref hasBounds, candidate); } } return hasBounds; } private static void AddBounds(ref Bounds bounds, ref bool hasBounds, Bounds candidate) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(((Bounds)(ref candidate)).center) && IsFinite(((Bounds)(ref candidate)).size)) { if (!hasBounds) { bounds = candidate; hasBounds = true; } else { ((Bounds)(ref bounds)).Encapsulate(candidate); } } } private static bool IsUsefulBounds(Bounds bounds, bool hasBounds) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) if (hasBounds && IsFinite(((Bounds)(ref bounds)).center) && IsFinite(((Bounds)(ref bounds)).size)) { Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude >= 0.0025000002f; } return false; } private static Vector3 Abs(Vector3 vector) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0021: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Abs(vector.x), Mathf.Abs(vector.y), Mathf.Abs(vector.z)); } private static bool IsFinite(Vector3 vector) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) if (IsFinite(vector.x) && IsFinite(vector.y)) { return IsFinite(vector.z); } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool TryFindFloorY(Vector3 worldPosition, float searchHeight, out float floorY) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) floorY = worldPosition.y; if (_floorMask == 0) { _floorMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "water" }); } int num = Physics.RaycastNonAlloc(worldPosition + Vector3.up * 0.25f, Vector3.down, FloorHits, searchHeight, _floorMask, (QueryTriggerInteraction)1); bool flag = false; float num2 = float.NegativeInfinity; for (int i = 0; i < num; i++) { RaycastHit val = FloorHits[i]; if (!(((RaycastHit)(ref val)).normal.y < 0.7f) && !(((RaycastHit)(ref val)).point.y > worldPosition.y + 0.2f) && !(((RaycastHit)(ref val)).point.y <= num2)) { num2 = ((RaycastHit)(ref val)).point.y; flag = true; } } if (flag) { floorY = num2; } return flag; } private static void DrawRing(LineRenderer ring, Vector3 center, float radius) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (ring.positionCount != 28) { ring.positionCount = 28; } for (int i = 0; i < 28; i++) { float num = (float)i / 28f * (float)Math.PI * 2f; Vector3 val = center + (Vector3.right * Mathf.Cos(num) + Vector3.forward * Mathf.Sin(num)) * radius; ring.SetPosition(i, val); } } private static void DrawDash(Vector3 from, Vector3 to, float length) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) _dashLine.positionCount = 2; _dashLine.SetPosition(0, from); _dashLine.SetPosition(1, to); Material material = ((Renderer)_dashLine).material; if (!((Object)(object)material == (Object)null)) { EnsureDashTexture(); material.mainTexture = (Texture)(object)_dashTexture; material.mainTextureScale = new Vector2(Mathf.Max(0.01f, length / 0.35f), 1f); material.mainTextureOffset = new Vector2((0f - Time.time) * 1.6f, 0f); } } private static void EnsureDashTexture() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_dashTexture != (Object)null)) { _dashTexture = new Texture2D(10, 1, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; Color[] array = (Color[])(object)new Color[10]; for (int i = 0; i < 10; i++) { array[i] = (Color)((i < 6) ? Color.white : new Color(1f, 1f, 1f, 0f)); } _dashTexture.SetPixels(array); _dashTexture.Apply(); } } private static bool ShouldCancelForUiOrState(Player player) { if (_state == null) { return false; } if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player || !((Character)player).InPlaceMode() || ((Character)player).IsDead()) { return true; } if ((Object)(object)_state.NetView == (Object)null || !_state.NetView.IsValid() || (Object)(object)_state.Piece == (Object)null) { return true; } if (IsUiBlockingInput() || Hud.IsPieceSelectionVisible()) { return true; } return ZInput.GetKeyDown((KeyCode)27, true); } private static bool IsUiBlockingInput() { if (!Menu.IsVisible() && !InventoryGui.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen()) { if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } return true; } private static void Cancel(Player player, bool showMessage) { if (_state != null && showMessage) { Message(player, "Move cancelled"); } _state = null; DestroyLine(); } private static GameObject GetPlacementGhost(Player player) { object? obj = PlacementGhostField?.GetValue(player); return (GameObject)((obj is GameObject) ? obj : null); } private static PlacementStatus GetPlacementStatus(Player player) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) object obj = PlacementStatusField?.GetValue(player); if (obj is PlacementStatus) { return (PlacementStatus)obj; } return (PlacementStatus)1; } private static void EnsureLine() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_lineObject != (Object)null)) { _lineObject = new GameObject("MoveBuildPieces_LinkVisuals"); Object.DontDestroyOnLoad((Object)(object)_lineObject); _dashLine = CreateLineRenderer("MoveBuildPieces_Dash", loop: false, tiled: true); _originRing = CreateLineRenderer("MoveBuildPieces_OriginRing", loop: true, tiled: false); _ghostRing = CreateLineRenderer("MoveBuildPieces_GhostRing", loop: true, tiled: false); SetLineVisible(visible: false); } } private static LineRenderer CreateLineRenderer(string name, bool loop, bool tiled) { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(_lineObject.transform, false); LineRenderer val2 = val.AddComponent<LineRenderer>(); val2.useWorldSpace = true; val2.loop = loop; val2.numCapVertices = 4; val2.numCornerVertices = 2; val2.textureMode = (LineTextureMode)(tiled ? 1 : 0); val2.alignment = (LineAlignment)0; val2.positionCount = 0; val2.widthMultiplier = 0.075f; val2.startColor = (loop ? RingColor : LinkColor); val2.endColor = (loop ? RingColor : LinkColor); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; Shader val3 = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); if ((Object)(object)val3 != (Object)null) { ((Renderer)val2).material = new Material(val3) { name = name + "_Material", renderQueue = 3100 }; } ((Renderer)val2).enabled = false; return val2; } private static void SetLineVisible(bool visible) { if ((Object)(object)_dashLine != (Object)null) { ((Renderer)_dashLine).enabled = visible; } if ((Object)(object)_originRing != (Object)null) { ((Renderer)_originRing).enabled = visible; } if ((Object)(object)_ghostRing != (Object)null) { ((Renderer)_ghostRing).enabled = visible; } } private static void DestroyLine() { if ((Object)(object)_lineObject != (Object)null) { Object.Destroy((Object)(object)_lineObject); } _lineObject = null; _dashLine = null; _originRing = null; _ghostRing = null; } private static void Message(Player player, string text) { if ((Object)(object)player != (Object)null) { ((Character)player).Message((MessageType)2, text, 0, (Sprite)null); } } }