Decompiled source of PlacementPlus v1.0.0
PlacementPlus.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("PlacementPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f452388be527279b2948ee6e0b6049bf014523ff")] [assembly: AssemblyProduct("PlacementPlus")] [assembly: AssemblyTitle("PlacementPlus")] [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 PlacementPlus { internal static class ApartmentShutters { internal static int SuppressLockdown; internal static bool Enabled => PlacementConfig.ApartmentShutters?.Value ?? true; internal static bool IsOurDoor(Interactable inter) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 try { if (inter == null || (SoCustomComparison)(object)inter.preset == (SoCustomComparison)null) { return false; } if ((int)inter.preset.specialCaseFlag != 5) { return false; } FurnitureLocation furnitureParent = inter.furnitureParent; return furnitureParent != null && furnitureParent.userPlaced; } catch { return false; } } internal static bool IsOurBreaker(Interactable inter) { //IL_001b: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 try { if (inter == null || (SoCustomComparison)(object)inter.preset == (SoCustomComparison)null) { return false; } SpecialCase specialCaseFlag = inter.preset.specialCaseFlag; if ((int)specialCaseFlag != 28 && (int)specialCaseFlag != 27 && (int)specialCaseFlag != 26) { return false; } FurnitureLocation furnitureParent = inter.furnitureParent; return furnitureParent != null && furnitureParent.userPlaced; } catch { return false; } } internal static NewAddress AddressOf(Interactable inter) { try { return (inter != null && inter.node != null && (Object)(object)inter.node.gameLocation != (Object)null) ? inter.node.gameLocation.thisAsAddress : null; } catch { return null; } } internal static void DriveDoors(Interactable breaker, bool sw0) { try { NewAddress val = AddressOf(breaker); if ((Object)(object)val == (Object)null || ((NewGameLocation)val).rooms == null) { return; } bool flag = true; try { flag = (Object)(object)SessionData.Instance != (Object)null && SessionData.Instance.startedGame; } catch { } List<NewRoom> rooms = ((NewGameLocation)val).rooms; for (int i = 0; i < rooms.Count; i++) { NewRoom val2 = rooms[i]; if ((Object)(object)val2 == (Object)null || val2.specialCaseInteractables == null || !val2.specialCaseInteractables.ContainsKey((SpecialCase)5)) { continue; } List<Interactable> val3 = val2.specialCaseInteractables[(SpecialCase)5]; if (val3 == null) { continue; } for (int j = 0; j < val3.Count; j++) { Interactable val4 = val3[j]; if (val4 == null || !IsOurDoor(val4)) { continue; } try { if (val4.sw0 != sw0) { val4.SetSwitchState(sw0, (Actor)null, flag, false, false); } } catch { } } } } catch { } } internal static void ForEachHomeDoorsBreaker(Action<Interactable> act) { try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } ProcessAddress(((Human)instance).home, act); List<NewAddress> apartmentsOwned = instance.apartmentsOwned; if (apartmentsOwned != null) { for (int i = 0; i < apartmentsOwned.Count; i++) { ProcessAddress(apartmentsOwned[i], act); } } } catch { } } private static void ProcessAddress(NewAddress addr, Action<Interactable> act) { try { if ((Object)(object)addr == (Object)null || ((NewGameLocation)addr).rooms == null) { return; } List<NewRoom> rooms = ((NewGameLocation)addr).rooms; for (int i = 0; i < rooms.Count; i++) { NewRoom val = rooms[i]; if ((Object)(object)val == (Object)null || val.specialCaseInteractables == null || !val.specialCaseInteractables.ContainsKey((SpecialCase)28)) { continue; } List<Interactable> val2 = val.specialCaseInteractables[(SpecialCase)28]; if (val2 == null) { continue; } for (int j = 0; j < val2.Count; j++) { Interactable val3 = val2[j]; if (val3 != null && IsOurBreaker(val3)) { try { act(val3); } catch { } } } } } catch { } } internal static void ResyncAll() { if (!Enabled) { return; } ForEachHomeDoorsBreaker(delegate(Interactable b) { try { DriveDoors(b, b.sw0); } catch { } }); } internal static void OpenSealedHomes() { ForEachHomeDoorsBreaker(delegate(Interactable b) { try { if (!b.sw0) { b.SetSwitchState(true, (Actor)null, true, false, false); DriveDoors(b, sw0: true); } } catch { } }); } } public class DecorProbe : MonoBehaviour { public DecorProbe(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) try { ConfigEntry<bool> enabled = PlacementConfig.Enabled; if (enabled != null && enabled.Value) { Player instance = Player.Instance; if ((!((Object)(object)instance != (Object)null) || instance.computerInteractable == null) && Input.GetKeyDown(PlacementConfig.ProbeKey.Value)) { DumpAll(); } } } catch { } } private void DumpAll() { StringBuilder stringBuilder = new StringBuilder(32768); List<string> list = new List<string>(); stringBuilder.Append("===== PlacementPlus DecorProbe @ ").Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append(" =====\n"); try { DumpFurnitureCensus(stringBuilder, list); } catch (Exception ex) { Line(stringBuilder, list, "[FURNITURE CENSUS FAILED: " + ex.Message + "]"); } try { DumpItemPlacementCensus(stringBuilder, list); } catch (Exception ex2) { Line(stringBuilder, list, "[ITEM PLACEMENT CENSUS FAILED: " + ex2.Message + "]"); } try { DumpCeilingMeasurements(stringBuilder, list); } catch (Exception ex3) { Line(stringBuilder, list, "[CEILING MEASUREMENT FAILED: " + ex3.Message + "]"); } try { DumpSurfaceProbe(stringBuilder, list); } catch (Exception ex4) { Line(stringBuilder, list, "[SURFACE PROBE FAILED: " + ex4.Message + "]"); } try { DumpSecurityFixtures(stringBuilder, list); } catch (Exception ex5) { Line(stringBuilder, list, "[SECURITY FIXTURE PROBE FAILED: " + ex5.Message + "]"); } stringBuilder.Append("===== end DecorProbe ====="); string text = stringBuilder.ToString(); ConfigEntry<bool> writeFile = PlacementConfig.WriteFile; string text2 = ((writeFile == null || writeFile.Value) ? WriteToFile(text) : null); Plugin.Log2.LogMessage((object)"[PlacementPlus] DecorProbe dump:"); foreach (string item in list) { Plugin.Log2.LogMessage((object)(" " + item)); } if (text2 != null) { Plugin.Log2.LogMessage((object)("[PlacementPlus] full census written to: " + text2)); } } private void DumpFurnitureCensus(StringBuilder sb, List<string> echo) { //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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) Toolbox instance = Toolbox.Instance; List<FurniturePreset> val = (((Object)(object)instance != (Object)null) ? instance.allFurniture : null); sb.Append("\n--- FURNITURE CENSUS ---\n"); if (val == null) { Line(sb, echo, "allFurniture is null (not loaded yet?)"); return; } int count = val.Count; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; sb.Append("status | name | decorClass | purchasable | disableFromMenu | hasPrefab | cost | class0\n"); Enumerator<FurniturePreset> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { FurniturePreset current = enumerator.Current; if ((SoCustomComparison)(object)current == (SoCustomComparison)null) { continue; } try { bool flag = (Object)(object)current.prefab != (Object)null; string value; if (!flag) { value = "UNPLACEABLE"; num4++; } else if (current.disableFromDecorMenu) { value = "HIDDEN-MENU"; num3++; } else if (!current.purchasable) { value = "HIDDEN-SHOP"; num2++; } else { value = "VISIBLE"; num++; } string value2 = "-"; if (current.classes != null && current.classes.Count > 0 && (SoCustomComparison)(object)current.classes[0] != (SoCustomComparison)null) { FurnitureClass val2 = current.classes[0]; StringBuilder stringBuilder = new StringBuilder(); if (val2.ceilingPiece) { stringBuilder.Append("CEIL "); } if (val2.wallPiece) { stringBuilder.Append("WALL "); } if (val2.useWallSnappingInDecorMode) { stringBuilder.Append("WSNAP "); } value2 = stringBuilder.ToString() + val2.objectSize.x.ToString("0.#") + "x" + val2.objectSize.y.ToString("0.#"); } sb.Append(value).Append(" | ").Append(SafeName((Object)(object)current)) .Append(" | ") .Append(((object)current.decorClass/*cast due to .constrained prefix*/).ToString()) .Append(" | p=") .Append(current.purchasable) .Append(" | dm=") .Append(current.disableFromDecorMenu) .Append(" | prefab=") .Append(flag) .Append(" | cost=") .Append(current.cost) .Append(" | ") .Append(value2) .Append('\n'); } catch (Exception ex) { sb.Append("[row error: ").Append(ex.Message).Append("]\n"); } } Line(sb, echo, $"furniture: {count} total | {num} visible | {num2} hidden-shop | {num3} hidden-menu | {num4} unplaceable"); } private unsafe void DumpItemPlacementCensus(StringBuilder sb, List<string> echo) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Invalid comparison between Unknown and I4 Il2CppArrayBase<InteractablePreset> val = Resources.FindObjectsOfTypeAll<InteractablePreset>(); sb.Append("\n--- ITEM PLACEMENT-MODE CENSUS ---\n"); if (val == null) { Line(sb, echo, "no InteractablePresets found"); return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int length = val.Length; StringBuilder stringBuilder = new StringBuilder(); sb.Append("name | apartmentPlacementMode | isInventoryItem | allowInStorage | mustTouchFurniture (non-physics rows only)\n"); for (int i = 0; i < val.Length; i++) { InteractablePreset val2 = val[i]; if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null) { continue; } try { ApartmentPlacementMode apartmentPlacementMode = val2.apartmentPlacementMode; bool isInventoryItem = val2.isInventoryItem; if ((int)apartmentPlacementMode == 2) { num3++; } else if ((int)apartmentPlacementMode == 1) { num2++; } else { num++; } if (isInventoryItem) { num4++; } if ((int)apartmentPlacementMode == 0) { continue; } int value = ((val2.mustTouchFurniture != null) ? val2.mustTouchFurniture.Count : 0); sb.Append(SafeName((Object)(object)val2)).Append(" | ").Append(((object)(*(ApartmentPlacementMode*)(&apartmentPlacementMode))/*cast due to .constrained prefix*/).ToString()) .Append(" | inv=") .Append(isInventoryItem) .Append(" | storage=") .Append(val2.allowInApartmentStorage) .Append(" | mustTouch=") .Append(value) .Append('\n'); if ((int)apartmentPlacementMode == 2) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(SafeName((Object)(object)val2)); } } catch { } } Line(sb, echo, $"items: {length} presets | physics={num} vertical(wall)={num2} ceiling={num3} | inventory={num4}"); Line(sb, echo, "ceiling-mode items (Path C targets): " + ((stringBuilder.Length > 0) ? stringBuilder.ToString() : "(none)")); } private void DumpCeilingMeasurements(StringBuilder sb, List<string> echo) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Invalid comparison between Unknown and I4 //IL_02ff: Unknown result type (might be due to invalid IL or missing references) sb.Append("\n--- CEILING MEASUREMENTS (current room) ---\n"); Player instance = Player.Instance; NewRoom val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentRoom : null); if ((Object)(object)val == (Object)null) { Line(sb, echo, "no current room (stand inside a room and press again)"); return; } sb.Append("room: ").Append(SafeRoomName(val)).Append('\n'); List<Interactable> mainLights = val.mainLights; int num = 0; if (mainLights != null) { Enumerator<Interactable> enumerator = mainLights.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; if (current != null) { try { float num2 = TrueCeilingY(current.node); float y = current.wPos.y; Line(sb, echo, $"mainLight '{InterName(current)}': y={y:0.###} trueCeiling={num2:0.###} gap={num2 - y:0.###}m (Path A)"); num++; } catch (Exception ex) { sb.Append(" [light err: ").Append(ex.Message).Append("]\n"); } } } } if (num == 0) { Line(sb, echo, "no main lights in this room"); } List<FurnitureLocation> individualFurniture = val.individualFurniture; int num3 = 0; if (individualFurniture != null) { Enumerator<FurnitureLocation> enumerator2 = individualFurniture.GetEnumerator(); while (enumerator2.MoveNext()) { FurnitureLocation current2 = enumerator2.Current; if (current2 == null) { continue; } try { if (current2.furnitureClasses != null && current2.furnitureClasses.Count != 0 && !((SoCustomComparison)(object)current2.furnitureClasses[0] == (SoCustomComparison)null) && current2.furnitureClasses[0].ceilingPiece) { GameObject spawnedObject = current2.spawnedObject; if (!((Object)(object)spawnedObject == (Object)null)) { float num4 = TrueCeilingY(current2.anchorNode); float y2 = spawnedObject.transform.position.y; float num5 = TopY(spawnedObject, y2); Line(sb, echo, $"ceilFurniture '{SafeName((Object)(object)current2.furnitureClasses[0])}': objY={y2:0.###} top={num5:0.###} trueCeiling={num4:0.###} gap(top->ceil)={num4 - num5:0.###}m (Path B)"); num3++; } } } catch (Exception ex2) { sb.Append(" [furn err: ").Append(ex2.Message).Append("]\n"); } } } if (num3 == 0) { Line(sb, echo, "no ceiling furniture placed in this room"); } try { InteractionController instance2 = InteractionController.Instance; InteractableController val2 = (((Object)(object)instance2 != (Object)null) ? instance2.carryingObject : null); if ((Object)(object)val2 != (Object)null && val2.interactable != null && (SoCustomComparison)(object)val2.interactable.preset != (SoCustomComparison)null && (int)val2.interactable.preset.apartmentPlacementMode == 2) { float num6 = TrueCeilingY(((Actor)instance).currentNode); float y3 = ((Component)val2).transform.position.y; float num7 = TopY(((Component)val2).gameObject, y3); Line(sb, echo, $"CARRIED ceiling item '{InterName(val2.interactable)}': objY={y3:0.###} top={num7:0.###} trueCeiling={num6:0.###} gap(top->ceil)={num6 - num7:0.###}m (Path C, while placing)"); } else { Line(sb, echo, "no ceiling-mode item carried — to measure Path C, hold a hanging light in placement mode and press again"); } } catch (Exception ex3) { sb.Append(" [carried err: ").Append(ex3.Message).Append("]\n"); } } private void DumpSurfaceProbe(StringBuilder sb, List<string> echo) { //IL_004f: 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_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_0063: 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_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) sb.Append("\n--- SURFACE PROBE (crosshair) ---\n"); Player instance = Player.Instance; Transform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.cam != (Object)null) ? ((Component)instance.cam).transform : null); if ((Object)(object)val == (Object)null) { Line(sb, echo, "no camera"); return; } Vector3 position = val.position; Vector3 forward = val.forward; ProbeMask(sb, echo, "layer29(wall/shell)", position, forward, 536870912); ProbeMask(sb, echo, "layer0(furniture) ", position, forward, 1); ProbeMask(sb, echo, "any-layer ", position, forward, -1); try { InteractionController instance2 = InteractionController.Instance; Interactable val2 = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.carryingObject != (Object)null) ? instance2.carryingObject.interactable : null); if (val2 == null) { InventorySlot val3 = (((Object)(object)BioScreenController.Instance != (Object)null) ? BioScreenController.Instance.selectedSlot : null); val2 = ((val3 != null) ? val3.GetInteractable() : null); } GameObject val4 = ((val2 != null) ? val2.spawnedObject : null); if ((Object)(object)val4 == (Object)null) { Line(sb, echo, "no carried/held item to measure (hold the silenced pistol and press again)"); return; } Line(sb, echo, "item renderers for '" + InterName(val2) + "':"); Il2CppArrayBase<Renderer> componentsInChildren = val4.GetComponentsInChildren<Renderer>(true); int num = componentsInChildren?.Length ?? 0; for (int i = 0; i < num && i < 12; i++) { Renderer val5 = componentsInChildren[i]; if (!((Object)(object)val5 == (Object)null)) { Bounds localBounds = val5.localBounds; object[] obj = new object[5] { i, SafeName((Object)(object)val5), Fmt(((Bounds)(ref localBounds)).center), Fmt(((Bounds)(ref localBounds)).extents), null }; Bounds bounds = val5.bounds; obj[4] = Fmt(((Bounds)(ref bounds)).center); Line(sb, echo, string.Format(" rend[{0}]={1} localCenter={2} localExtents={3} worldCenter={4}", obj)); } } } catch (Exception ex) { Line(sb, echo, "[item measure err: " + ex.Message + "]"); } } private static void ProbeMask(StringBuilder sb, List<string> echo, string label, Vector3 o, Vector3 d, int mask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) try { RaycastHit val = default(RaycastHit); if (Physics.Raycast(o, d, ref val, 10f, mask, (QueryTriggerInteraction)1)) { Collider collider = ((RaycastHit)(ref val)).collider; GameObject val2 = (((Object)(object)collider != (Object)null) ? ((Component)collider).gameObject : null); int num = (((Object)(object)val2 != (Object)null) ? val2.layer : (-1)); string text = "?"; try { text = LayerMask.LayerToName(num); } catch { } Line(sb, echo, string.Format("{0}: hit='{1}' layer={2}({3}) tag={4} dist={5:0.###} point={6}", label, ((Object)(object)collider != (Object)null) ? SafeName((Object)(object)collider) : "?", num, text, SafeTag(val2), ((RaycastHit)(ref val)).distance, Fmt(((RaycastHit)(ref val)).point))); } else { Line(sb, echo, label + ": no hit"); } } catch (Exception ex) { Line(sb, echo, label + ": err " + ex.Message); } } private static string SafeTag(GameObject go) { try { return ((Object)(object)go != (Object)null) ? go.tag : "-"; } catch { return "?"; } } private static string Fmt(Vector3 v) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:0.##},{v.y:0.##},{v.z:0.##})"; } private void DumpSecurityFixtures(StringBuilder sb, List<string> echo) { //IL_025c: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Invalid comparison between Unknown and I4 //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 sb.Append("\n--- SECURITY FIXTURE PRESETS (breaker/door integrated interactables) ---\n"); Toolbox instance = Toolbox.Instance; List<FurniturePreset> val = (((Object)(object)instance != (Object)null) ? instance.allFurniture : null); if (val == null) { Line(sb, echo, "allFurniture null"); return; } int num = 0; Enumerator<FurniturePreset> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { FurniturePreset current = enumerator.Current; if ((SoCustomComparison)(object)current == (SoCustomComparison)null) { continue; } try { List<IntegratedInteractable> integratedInteractables = current.integratedInteractables; if (integratedInteractables == null || integratedInteractables.Count == 0) { continue; } bool flag = false; for (int i = 0; i < integratedInteractables.Count; i++) { InteractablePreset val2 = ((integratedInteractables[i] != null) ? integratedInteractables[i].preset : null); if (!((SoCustomComparison)(object)val2 == (SoCustomComparison)null)) { SpecialCase specialCaseFlag = val2.specialCaseFlag; if ((int)specialCaseFlag == 5 || (int)specialCaseFlag == 28 || (int)specialCaseFlag == 27 || (int)specialCaseFlag == 26) { flag = true; break; } } } if (!flag) { continue; } num++; Line(sb, echo, "FURNITURE '" + SafeName((Object)(object)current) + "' (purchasable=" + current.purchasable + ")"); for (int j = 0; j < integratedInteractables.Count; j++) { InteractablePreset val3 = ((integratedInteractables[j] != null) ? integratedInteractables[j].preset : null); if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null) { continue; } string text = ""; try { List<InteractionAction> actions = val3.GetActions(0); if (actions != null) { for (int k = 0; k < actions.Count && k < 8; k++) { InteractionAction val4 = actions[k]; if (val4 != null) { if (text.Length > 0) { text += ", "; } text = text + (((SoCustomComparison)(object)val4.action != (SoCustomComparison)null) ? ((Object)val4.action).name : "?") + (string.IsNullOrEmpty(val4.interactionName) ? "" : ("[" + val4.interactionName + "]")); } } } } catch (Exception ex) { text = "(actions err: " + ex.Message + ")"; } Line(sb, echo, " inter '" + SafeName((Object)(object)val3) + "' flag=" + ((object)val3.specialCaseFlag/*cast due to .constrained prefix*/).ToString() + " startSwitch=" + val3.startingSwitchState + " startLock=" + val3.startingLockState + " reset=" + val3.resetSwitchStates + "/" + val3.resetTimer.ToString("0.##") + " padlock=" + (((SoCustomComparison)(object)val3.includeLock != (SoCustomComparison)null) ? SafeName((Object)(object)val3.includeLock) : "none")); Line(sb, echo, " actions: " + ((text.Length > 0) ? text : "(none)")); } } catch (Exception ex2) { sb.Append("[fixture err: ").Append(ex2.Message).Append("]\n"); } } Line(sb, echo, "security fixtures found: " + num); } private static float TrueCeilingY(NewNode node) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (node == null) { return float.NaN; } return node.position.y + (float)node.floor.defaultCeilingHeight * 0.1f - (float)node.floorHeight * 0.1f; } private static float TopY(GameObject go, float fallback) { //IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references) try { Renderer componentInChildren = go.GetComponentInChildren<Renderer>(); if ((Object)(object)componentInChildren != (Object)null) { Bounds bounds = componentInChildren.bounds; return ((Bounds)(ref bounds)).max.y; } } catch { } return fallback; } private static string SafeName(Object o) { try { return (o != (Object)null) ? o.name : "null"; } catch { return "?"; } } private static string InterName(Interactable inter) { try { if (inter != null && (SoCustomComparison)(object)inter.preset != (SoCustomComparison)null) { return ((Object)inter.preset).name; } } catch { } return "item"; } private static string SafeRoomName(NewRoom room) { try { return room.name; } catch { } try { return ((SoCustomComparison)(object)room.preset != (SoCustomComparison)null) ? ((Object)room.preset).name : "room"; } catch { return "room"; } } private static void Line(StringBuilder sb, List<string> echo, string s) { sb.Append(s).Append('\n'); echo.Add(s); } private string WriteToFile(string text) { try { string text2 = Path.Combine(Paths.BepInExRootPath, "PlacementPlus"); Directory.CreateDirectory(text2); string text3 = Path.Combine(text2, "decor_census_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".txt"); File.WriteAllText(text3, text); return text3; } catch (Exception ex) { Plugin.Log2.LogWarning((object)("[PlacementPlus] file write failed: " + ex.Message)); return null; } } } internal static class Diag { internal static void DumpAnchors(string tag, Interactable inter) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) try { if (!PlacementController.Verbose || inter == null) { return; } InteractableController controller = inter.controller; Transform val = (((Object)(object)inter.spawnedObject != (Object)null) ? inter.spawnedObject.transform : null); Transform val2 = (((Object)(object)controller != (Object)null) ? ((Component)controller).transform : null); Transform val3 = (((Object)(object)controller != (Object)null) ? controller.alternativePhysicsParent : null); Transform val4 = (((Object)(object)val3 != (Object)null) ? val3 : val2); string text = PlacementController.PresetName(inter); bool flag = (Object)(object)val3 == (Object)null; bool flag2 = (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && (Object)(object)val == (Object)(object)val2; bool flag3 = (Object)(object)val4 != (Object)null && (Object)(object)val != (Object)null && val4.IsChildOf(val); ManualLogSource log = Plugin.Log2; bool flag4 = default(bool); BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(93, 8, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altNull="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootIsCtrl="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("tChildOfRoot="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag3); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootParent="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlParent="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val2)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altParent="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val3)); } log.LogWarning(val5); ManualLogSource log2 = Plugin.Log2; val5 = new BepInExWarningLogInterpolatedStringHandler(87, 9, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootEul="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | "); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("ctrlPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val2)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlEul="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val2)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | altPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val3)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altEul="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val3)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | wPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(PlacementController.V(inter.wPos)); } log2.LogWarning(val5); if (!((Object)(object)val != (Object)null)) { return; } Il2CppArrayBase<Renderer> componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); int num = componentsInChildren?.Length ?? 0; for (int i = 0; i < num && i < 12; i++) { Renderer val6 = componentsInChildren[i]; if (!((Object)(object)val6 == (Object)null)) { bool flag5 = (Object)(object)val4 != (Object)null && ((Component)val6).transform.IsChildOf(val4); ManualLogSource log3 = Plugin.Log2; val5 = new BepInExWarningLogInterpolatedStringHandler(47, 6, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rend["); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(i); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("]="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)val6).name); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" underT="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag5); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" center="); BepInExWarningLogInterpolatedStringHandler obj = val5; Bounds bounds = val6.bounds; ((BepInExLogInterpolatedStringHandler)obj).AppendFormatted<string>(PlacementController.V(((Bounds)(ref bounds)).center)); } log3.LogWarning(val5); } } } catch { } } internal static void DumpPhysState(string tag, Interactable inter) { //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Expected O, but got Unknown //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_041a: 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) try { if (!PlacementController.Verbose || inter == null) { return; } InteractableController controller = inter.controller; Transform val = (((Object)(object)inter.spawnedObject != (Object)null) ? inter.spawnedObject.transform : null); string text = PlacementController.PresetName(inter); float num = -1f; Vector3 euler; try { if (FrozenMark.TryGetPose(inter, out var pos, out euler)) { num = Vector3.Distance(inter.wPos, pos); } } catch { } bool flag = false; try { flag = FrozenMark.IsFrozen(inter); } catch { } string text2 = "rb=null"; bool flag2 = false; string text3 = "coll=?"; if ((Object)(object)controller != (Object)null) { try { flag2 = ((Behaviour)controller).enabled; } catch { } try { if ((Object)(object)controller.rb != (Object)null) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(27, 4); defaultInterpolatedStringHandler.AppendLiteral("rb[kin="); defaultInterpolatedStringHandler.AppendFormatted(controller.rb.isKinematic); defaultInterpolatedStringHandler.AppendLiteral(" grav="); defaultInterpolatedStringHandler.AppendFormatted(controller.rb.useGravity); defaultInterpolatedStringHandler.AppendLiteral(" vel="); euler = controller.rb.velocity; defaultInterpolatedStringHandler.AppendFormatted(((Vector3)(ref euler)).magnitude, "0.##"); defaultInterpolatedStringHandler.AppendLiteral(" detect="); defaultInterpolatedStringHandler.AppendFormatted(controller.rb.detectCollisions); defaultInterpolatedStringHandler.AppendLiteral("]"); text2 = defaultInterpolatedStringHandler.ToStringAndClear(); } } catch { } try { if ((Object)(object)controller.coll != (Object)null) { text3 = $"coll[en={controller.coll.enabled} trig={controller.coll.isTrigger}]"; } } catch { } } bool flag3 = false; int num2 = 0; int num3 = 0; bool flag4 = false; try { flag3 = (Object)(object)inter.spawnedObject != (Object)null && inter.spawnedObject.activeInHierarchy; } catch { } try { if ((Object)(object)val != (Object)null) { Il2CppArrayBase<Renderer> componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); num3 = componentsInChildren?.Length ?? 0; for (int i = 0; i < num3; i++) { Renderer val2 = componentsInChildren[i]; if (!((Object)(object)val2 == (Object)null)) { if (val2.enabled) { num2++; } if (val2.isVisible) { flag4 = true; } } } } } catch { } string text4 = "room=?"; try { NewNode node = inter.node; NewRoom val3 = ((node != null) ? node.room : null); bool value = (Object)(object)val3 != (Object)null && (Object)(object)Player.Instance != (Object)null && (Object)(object)val3 == (Object)(object)((Actor)Player.Instance).currentRoom; text4 = $"room[{(((Object)(object)val3 != (Object)null) ? val3.name : "null")} isCur={value}]"; } catch { } string text5 = "anc:"; try { Transform val4 = val; int num4 = 0; while ((Object)(object)val4 != (Object)null && num4 < 7) { text5 += $" {((Object)val4).name}={((Component)val4).gameObject.activeSelf}"; val4 = val4.parent; num4++; } } catch { } ManualLogSource log = Plugin.Log2; bool flag5 = default(bool); BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(110, 15, ref flag5); if (flag5) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][WATCH "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" wPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(PlacementController.V(inter.wPos)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("rootPos="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)(object)val != (Object)null) ? PlacementController.V(val.position) : "-"); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" distFromStored="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<float>(num, "0.###"); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("active="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag3); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rendersOn="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num3); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" onScreen="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag4); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" frozen="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlEnabled="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text3); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text4); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text5); } log.LogWarning(val5); } catch { } } private static string ParentName(Transform tr) { try { return ((Object)(object)tr != (Object)null && (Object)(object)tr.parent != (Object)null) ? ((Object)tr.parent).name : "-"; } catch { return "?"; } } private static string P(Transform tr) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) try { return ((Object)(object)tr != (Object)null) ? PlacementController.V(tr.position) : "-"; } catch { return "?"; } } private static string E(Transform tr) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) try { return ((Object)(object)tr != (Object)null) ? PlacementController.V(tr.eulerAngles) : "-"; } catch { return "?"; } } } internal static class FrozenMark { private const int FrozenVarInt = 7777; internal static bool IsFrozen(Interactable inter) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 try { List<Passed> val = ((inter != null) ? inter.pv : null); if (val == null) { return false; } for (int i = 0; i < val.Count; i++) { if (val[i] != null && (int)val[i].varType == 7777) { return true; } } } catch { } return false; } internal static void SetFrozen(Interactable inter, Vector3 pos, Vector3 euler) { //IL_0028: 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_0044: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown try { if (inter != null && inter.pv != null) { ClearFrozen(inter); string text = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3},{4},{5}", pos.x, pos.y, pos.z, euler.x, euler.y, euler.z); inter.pv.Add(new Passed((PassedVarType)7777, 0f, text)); } } catch { } } internal static void ClearFrozen(Interactable inter) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 try { List<Passed> val = ((inter != null) ? inter.pv : null); if (val == null) { return; } for (int num = val.Count - 1; num >= 0; num--) { if (val[num] != null && (int)val[num].varType == 7777) { val.RemoveAt(num); } } } catch { } } internal static bool TryGetPose(Interactable inter, out Vector3 pos, out Vector3 euler) { //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_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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0097: 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_00bd: 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) pos = Vector3.zero; euler = Vector3.zero; try { List<Passed> val = ((inter != null) ? inter.pv : null); if (val == null) { return false; } for (int i = 0; i < val.Count; i++) { Passed val2 = val[i]; if (val2 != null && (int)val2.varType == 7777) { string str = val2.str; if (string.IsNullOrEmpty(str)) { return false; } string[] array = str.Split(','); if (array.Length < 6) { return false; } pos = new Vector3(F(array[0]), F(array[1]), F(array[2])); euler = new Vector3(F(array[3]), F(array[4]), F(array[5])); return true; } } } catch { } return false; } private static float F(string s) { if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 0f; } return result; } } internal static class Gate { internal static bool InPlay() { try { SessionData instance = SessionData.Instance; if ((Object)(object)instance == (Object)null || !instance.play) { return false; } Player instance2 = Player.Instance; if ((Object)(object)instance2 == (Object)null || ((Actor)instance2).isDead) { return false; } if (instance2.computerInteractable != null) { return false; } return true; } catch { return false; } } internal static bool TextOrPopupActive() { try { InterfaceController instance = InterfaceController.Instance; if ((Object)(object)instance != (Object)null && instance.playerTextInputActive) { return true; } PopupMessageController instance2 = PopupMessageController.Instance; if ((Object)(object)instance2 != (Object)null && instance2.active) { return true; } return false; } catch { return true; } } internal static bool VanillaDecorActive() { try { SessionData instance = SessionData.Instance; if ((Object)(object)instance != (Object)null && instance.isDecorEdit) { return true; } PlayerApartmentController instance2 = PlayerApartmentController.Instance; if ((Object)(object)instance2 != (Object)null && (instance2.furniturePlacementMode || instance2.decoratingMode)) { return true; } return false; } catch { return false; } } } internal static class PlacementConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyCode> ProbeKey; internal static ConfigEntry<bool> WriteFile; internal static ConfigEntry<bool> PrecisionPlacement; internal static ConfigEntry<float> MaxDistance; internal static ConfigEntry<bool> AllowPitchRoll; internal static ConfigEntry<bool> ShowOverlay; internal static ConfigEntry<bool> SurfaceClearance; internal static ConfigEntry<bool> FixtureMoveAway; internal static ConfigEntry<bool> SurfaceHidden; internal static ConfigEntry<string> Allowlist; internal static ConfigEntry<int> Price; internal static ConfigEntry<bool> HideUnplaceable; internal static ConfigEntry<bool> CeilingFixItems; internal static ConfigEntry<bool> ApartmentShutters; internal const string DefaultAllowlist = "VintageWallLampBallroom,FlowerBed,FlowerBedCorner,FlowerBedOld,BushBuddleia,BushMossy,Tree,TreeTall,BasketballHoop,PublicCorkboard,MagazineStand,Newsstand,HotelDeskLong,MoldedWaitingSeats,SyncBed,UnderDeskDrawers,LockersX6,HotelKeyRack,WashingMachines,Loudspeaker,TelevisionBillboard,SecurityCamera,SentryGun,ScoutLaser,CCTVTower,TelephoneBooth,AmusementRide,SupermarketFridge,SupermarketFreezer,SupermarketFreezerCorner,SupermarketShelving1,SupermarketShelving2,SupermarketEndShelf,SupermarketEmptyShelfLarge,SupermarketEmptyShelfSmall,SupermarketCounterLeft,SupermarketCounterRight,SupermarketScales,SupermarketSignSynthBeef,SupermarketSignStarch,ShopCounter,FruitStand,FruitStandApples,FruitStandBananas,FruitStandCabbages,NoodleStand,SynthFishStand,BasketStack,OpenSign,24HrSign,HotelWelcomeSign,FlowerBedOldCorner,HospitalBed,WalkInClosetItems,ClosetSlatDoors,TallJunkShelfDouble,IndustrialMachineShort,IndustrialMachineLong,IndustrialMachineLarge,IndustrialMachineCylinder,Loom,CableSpool,PowerBox,BreakerBox,RouterBox,NewspaperBox,ElGenSyncMachine,BurningBarrel,DinerWindowShelf,SecurityDoorDouble,SecurityDoorTriple,TelephoneBox,BathroomScales,TrousersOnFloor,ShirtOnFloor,DressOnFloor,ClothesPile,Graffiti,WallGrimeTop,WallGrimeBottom,LitterDecal,StaticCeilingRotLong,StaticCeilingRotShort,StaticCeilingRotCorner,Bollard,Hydrant,MooringPost"; internal static ConfigEntry<bool> PutBackRestorePose; internal static ConfigEntry<KeyCode> EnterKey; internal static ConfigEntry<KeyCode> NudgeForward; internal static ConfigEntry<KeyCode> NudgeBack; internal static ConfigEntry<KeyCode> NudgeLeft; internal static ConfigEntry<KeyCode> NudgeRight; internal static ConfigEntry<KeyCode> NudgeUp; internal static ConfigEntry<KeyCode> NudgeDown; internal static ConfigEntry<KeyCode> RotateCCW; internal static ConfigEntry<KeyCode> RotateCW; internal static ConfigEntry<KeyCode> CycleAxis; internal static ConfigEntry<KeyCode> Confirm; internal static ConfigEntry<KeyCode> Reset; internal static ConfigEntry<KeyCode> CoarseMod; internal static ConfigEntry<KeyCode> FineMod; internal static ConfigEntry<KeyCode> CopyRot; internal static ConfigEntry<KeyCode> PasteRot; internal static void Init(ConfigFile cfg) { Enabled = cfg.Bind<bool>("Debug", "Enabled", false, "Enable the DecorProbe diagnostic (a dev tool that only reads and logs). Independent of the gameplay features."); ProbeKey = cfg.Bind<KeyCode>("Debug", "ProbeKey", (KeyCode)290, "Key to dump the decor census + item placement modes + ceiling measurements to the log (and a text file)."); WriteFile = cfg.Bind<bool>("Debug", "WriteFile", true, "Also write each probe dump to BepInEx/PlacementPlus/decor_census_*.txt."); PrecisionPlacement = cfg.Bind<bool>("Items", "PrecisionPlacement", true, "Master switch for precision item placement (the enter-key mode that pins a held/carried object so you can move + rotate it freely, then place it)."); MaxDistance = cfg.Bind<float>("Items", "MaxDistance", 10f, "Maximum distance (metres) you can push a pinned object away from yourself."); AllowPitchRoll = cfg.Bind<bool>("Items", "AllowPitchRoll", true, "Allow tilting items on all three axes (pitch/roll as well as yaw). Turn off for yaw-only."); ShowOverlay = cfg.Bind<bool>("Items", "ShowOverlay", true, "Show a small on-screen control hint while in placement mode."); SurfaceClearance = cfg.Bind<bool>("Items", "SurfaceClearance", true, "When placing an item, nudge it out of any wall/floor/ceiling its mesh is sunk into, so long or asymmetric items (silencers, barrels, scopes) can't clip behind a panel and become unpickable. Only pushes along the buried surface; never moves an item sitting clear of a wall, and never treats furniture (racks/shelves/doors) as an obstacle."); FixtureMoveAway = cfg.Bind<bool>("Fixtures", "MoveAway", true, "While placing furniture from the decor menu, use the same move keys (arrows) to push the preview further away or pull it closer/sideways, instead of it being stuck ~1m in front of you. Wall pieces keep their vanilla aim-at-wall behaviour. Height stays game-controlled."); SurfaceHidden = cfg.Bind<bool>("Fixtures", "SurfaceHidden", true, "Add a curated set of normally-hidden fixtures to the decor shop (see Allowlist). Session-only: turning this off and restarting fully reverts."); Allowlist = cfg.Bind<string>("Fixtures", "Allowlist", "VintageWallLampBallroom,FlowerBed,FlowerBedCorner,FlowerBedOld,BushBuddleia,BushMossy,Tree,TreeTall,BasketballHoop,PublicCorkboard,MagazineStand,Newsstand,HotelDeskLong,MoldedWaitingSeats,SyncBed,UnderDeskDrawers,LockersX6,HotelKeyRack,WashingMachines,Loudspeaker,TelevisionBillboard,SecurityCamera,SentryGun,ScoutLaser,CCTVTower,TelephoneBooth,AmusementRide,SupermarketFridge,SupermarketFreezer,SupermarketFreezerCorner,SupermarketShelving1,SupermarketShelving2,SupermarketEndShelf,SupermarketEmptyShelfLarge,SupermarketEmptyShelfSmall,SupermarketCounterLeft,SupermarketCounterRight,SupermarketScales,SupermarketSignSynthBeef,SupermarketSignStarch,ShopCounter,FruitStand,FruitStandApples,FruitStandBananas,FruitStandCabbages,NoodleStand,SynthFishStand,BasketStack,OpenSign,24HrSign,HotelWelcomeSign,FlowerBedOldCorner,HospitalBed,WalkInClosetItems,ClosetSlatDoors,TallJunkShelfDouble,IndustrialMachineShort,IndustrialMachineLong,IndustrialMachineLarge,IndustrialMachineCylinder,Loom,CableSpool,PowerBox,BreakerBox,RouterBox,NewspaperBox,ElGenSyncMachine,BurningBarrel,DinerWindowShelf,SecurityDoorDouble,SecurityDoorTriple,TelephoneBox,BathroomScales,TrousersOnFloor,ShirtOnFloor,DressOnFloor,ClothesPile,Graffiti,WallGrimeTop,WallGrimeBottom,LitterDecal,StaticCeilingRotLong,StaticCeilingRotShort,StaticCeilingRotCorner,Bollard,Hydrant,MooringPost", "Comma-separated FurniturePreset names to surface in the decor shop. Edit freely; run the DecorProbe (F9) to see every available name."); Price = cfg.Bind<int>("Fixtures", "Price", 50, "Flat price applied to every surfaced fixture (you pay for decor in-game)."); HideUnplaceable = cfg.Bind<bool>("Fixtures", "HideUnplaceable", true, "Hide fixtures the apartment decor editor cannot actually place. Ceiling-mounted pieces are blocked by air ducts in almost every apartment tile, so they never place. Turn off to offer them anyway (they place only in rare duct-free spots)."); CeilingFixItems = cfg.Bind<bool>("CeilingFix", "Items", true, "Fix player-placed ceiling lights that hang ~1m below the ceiling (the vanilla item-ceiling placement bug). Snaps the fixture's top to the ceiling. Does not touch vanilla room lights."); ApartmentShutters = cfg.Bind<bool>("Security", "ApartmentShutters", true, "Make a breaker box + security doors you place in your OWN apartment work as a self-contained privacy shutter: flipping the breaker's doors switch closes/opens only that apartment's doors, with no whole-floor lockdown. Fully isolated from the floor's security system and never affects vanilla alarms. Only affects fixtures you place yourself."); PutBackRestorePose = cfg.Bind<bool>("PutBack", "RestorePose", true, "When you drop an item near where it was, the game's native put-back returns its position but loses its rotation. This restores the exact placed rotation (and re-freezes display-placed items)."); EnterKey = cfg.Bind<KeyCode>("Keys", "EnterPlacement", (KeyCode)118, "Enter precision placement for the held/carried item (press again to cancel)."); NudgeForward = cfg.Bind<KeyCode>("Keys", "NudgeForward", (KeyCode)273, "Move the pinned object away from you."); NudgeBack = cfg.Bind<KeyCode>("Keys", "NudgeBack", (KeyCode)274, "Move the pinned object toward you."); NudgeLeft = cfg.Bind<KeyCode>("Keys", "NudgeLeft", (KeyCode)276, "Move the pinned object left."); NudgeRight = cfg.Bind<KeyCode>("Keys", "NudgeRight", (KeyCode)275, "Move the pinned object right."); NudgeUp = cfg.Bind<KeyCode>("Keys", "NudgeUp", (KeyCode)280, "Raise the pinned object (Home also works if you rebind)."); NudgeDown = cfg.Bind<KeyCode>("Keys", "NudgeDown", (KeyCode)281, "Lower the pinned object."); RotateCCW = cfg.Bind<KeyCode>("Keys", "RotateCCW", (KeyCode)44, "Rotate the active axis counter-clockwise."); RotateCW = cfg.Bind<KeyCode>("Keys", "RotateCW", (KeyCode)46, "Rotate the active axis clockwise."); CycleAxis = cfg.Bind<KeyCode>("Keys", "CycleAxis", (KeyCode)116, "Cycle the rotation axis (yaw -> pitch -> roll)."); Confirm = cfg.Bind<KeyCode>("Keys", "Confirm", (KeyCode)13, "Place the object statically at the previewed pose."); Reset = cfg.Bind<KeyCode>("Keys", "Reset", (KeyCode)8, "Reset tilt (pitch/roll to 0, yaw to the nearest 45 degrees)."); CoarseMod = cfg.Bind<KeyCode>("Keys", "CoarseModifier", (KeyCode)304, "Hold for larger move/rotate steps."); FineMod = cfg.Bind<KeyCode>("Keys", "FineModifier", (KeyCode)308, "Hold for finer move/rotate steps (Alt, not Ctrl, to avoid the crouch/sprint keys)."); CopyRot = cfg.Bind<KeyCode>("Keys", "CopyRotation", (KeyCode)111, "While placing, store the current rotation/orientation (not position) so you can apply it to other items. (O = copy Orientation; C is the game's crouch key.)"); PasteRot = cfg.Bind<KeyCode>("Keys", "PasteRotation", (KeyCode)112, "While placing, apply the stored rotation/orientation to the current item, for lining several items up the same way."); } } public class PlacementController : MonoBehaviour { private sealed class Watch { public Interactable inter; public int start; public int stage; } internal static bool EntryBInProgress; internal static Interactable PendingDiag; private static bool _clearanceWarned; private static bool _shutterResyncDone; internal static Vector3? CopiedEuler; private static readonly List<Watch> _watch = new List<Watch>(); internal static float FixtureOffsetX; internal static float FixtureOffsetZ; private static PlacementController _inst; private bool _active; private Interactable _target; private int _targetId = -1; private InteractableController _ctrl; private Vector3 _anchor; private Vector3 _euler; private int _axis; private bool _fromHand; private readonly Dictionary<KeyCode, float> _repeatAt = new Dictionary<KeyCode, float>(); private Player _lastPlayer; private bool _fixtureWas; internal static bool ModeActive { get { if ((Object)(object)_inst != (Object)null) { return _inst._active; } return false; } } internal static bool Verbose => PlacementConfig.Enabled?.Value ?? false; public PlacementController(IntPtr ptr) : base(ptr) { } internal static void WatchAfterPutback(Interactable inter) { try { if (inter != null) { _watch.Add(new Watch { inter = inter, start = Time.frameCount, stage = 0 }); } } catch { } } private static void TickWatch() { try { int frameCount = Time.frameCount; int[] array = new int[3] { 15, 45, 90 }; for (int num = _watch.Count - 1; num >= 0; num--) { Watch watch = _watch[num]; if (watch.inter == null) { _watch.RemoveAt(num); } else { while (watch.stage < array.Length && frameCount - watch.start >= array[watch.stage]) { Diag.DumpPhysState("PB+" + array[watch.stage] + "f", watch.inter); watch.stage++; } if (watch.stage >= array.Length) { _watch.RemoveAt(num); } } } } catch { } } internal static string V(Vector3 v) { //IL_0017: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:0.##},{v.y:0.##},{v.z:0.##})"; } internal static string PresetName(Interactable inter) { try { return (inter != null && (SoCustomComparison)(object)inter.preset != (SoCustomComparison)null) ? ((Object)inter.preset).name : "?"; } catch { return "?"; } } private void Awake() { _inst = this; } private void OnDestroy() { if ((Object)(object)_inst == (Object)(object)this) { _inst = null; } } private void Update() { //IL_014e: Unknown result type (might be due to invalid IL or missing references) try { if (PendingDiag != null) { Interactable pendingDiag = PendingDiag; PendingDiag = null; Diag.DumpAnchors("PUTBACK-NEXTFRAME", pendingDiag); } if (_watch.Count > 0) { TickWatch(); } Player instance = Player.Instance; if ((Object)(object)instance != (Object)(object)_lastPlayer) { _lastPlayer = instance; EntryBInProgress = false; _shutterResyncDone = false; if (_active) { Exit(placed: false); } } if (!_shutterResyncDone && (Object)(object)instance != (Object)null) { try { if ((Object)(object)SessionData.Instance != (Object)null && SessionData.Instance.startedGame && Gate.InPlay()) { _shutterResyncDone = true; ApartmentShutters.ResyncAll(); } } catch { _shutterResyncDone = true; } } PlayerApartmentController instance2 = PlayerApartmentController.Instance; if ((Object)(object)instance2 != (Object)null && instance2.furniturePlacementMode) { if (!_fixtureWas) { FixtureOffsetX = 0f; FixtureOffsetZ = 0f; _fixtureWas = true; } if (_active) { Exit(placed: false); } ConfigEntry<bool> fixtureMoveAway = PlacementConfig.FixtureMoveAway; if (fixtureMoveAway == null || fixtureMoveAway.Value) { HandleFixtureNudge(); } return; } _fixtureWas = false; ConfigEntry<bool> precisionPlacement = PlacementConfig.PrecisionPlacement; if (precisionPlacement != null && !precisionPlacement.Value) { if (_active) { Exit(placed: false); } return; } if (!_active) { if (Input.GetKeyDown(PlacementConfig.EnterKey.Value)) { TryEnter(); } return; } if (!Gate.InPlay() || Gate.TextOrPopupActive()) { Exit(placed: false); return; } InteractableController val = (((Object)(object)InteractionController.Instance != (Object)null) ? InteractionController.Instance.carryingObject : null); if ((Object)(object)val == (Object)null || (Object)(object)_ctrl == (Object)null || (Object)(object)val != (Object)(object)_ctrl) { Exit(placed: false); } else { HandleKeys(); } } catch { try { Exit(placed: false); } catch { } } } private void LateUpdate() { //IL_0044: 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_004f: Unknown result type (might be due to invalid IL or missing references) if (!_active || (Object)(object)_ctrl == (Object)null) { return; } try { (((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent : ((Component)_ctrl).transform).SetPositionAndRotation(_anchor, Quaternion.Euler(_euler)); } catch { Exit(placed: false); } } private void TryEnter() { if (Gate.TextOrPopupActive() || Gate.VanillaDecorActive() || !Gate.InPlay()) { return; } InteractionController instance = InteractionController.Instance; if ((Object)(object)instance == (Object)null) { return; } if ((Object)(object)instance.carryingObject != (Object)null) { EnterFromCarry(instance.carryingObject); return; } InventorySlot val = (((Object)(object)BioScreenController.Instance != (Object)null) ? BioScreenController.Instance.selectedSlot : null); Interactable val2 = ((val != null) ? val.GetInteractable() : null); if (val2 != null) { EnterFromHand(val2); } } private void EnterFromCarry(InteractableController co) { //IL_0055: 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_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) _ctrl = co; _target = co.interactable; _targetId = ((_target != null) ? _target.id : (-1)); _fromHand = false; Transform val = (((Object)(object)co.alternativePhysicsParent != (Object)null) ? co.alternativePhysicsParent : ((Component)co).transform); _anchor = InitialAnchor(co); _euler = val.eulerAngles; _axis = 0; _active = true; Announce(); } private void EnterFromHand(Interactable held) { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) try { InventorySlot selectedSlot = BioScreenController.Instance.selectedSlot; EntryBInProgress = true; bool flag = false; try { flag = held.IsSpawnPositionRelevent(); } catch { } try { try { held.SetSpawnPositionRelevent(false); } catch { } FirstPersonItemController.Instance.EmptySlot(selectedSlot, false, false, false, false); } finally { EntryBInProgress = false; try { if (flag) { held.SetSpawnPositionRelevent(true); } } catch { } } ActionController.Instance.PickUp(held, ((Actor)Player.Instance).currentNode, (Actor)(object)Player.Instance); try { held.SetPhysicsPickupState(true, (Actor)(object)Player.Instance, true, false); } catch { } InteractableController carryingObject = InteractionController.Instance.carryingObject; if ((Object)(object)carryingObject == (Object)null || carryingObject.interactable == null) { Plugin.Log2.LogWarning((object)"[PlacementPlus] could not convert the held item to a carried object; returning it to the hand."); try { FirstPersonItemController.Instance.PickUpItem(held, true, false, true, true, true); return; } catch { return; } } _ctrl = carryingObject; _target = carryingObject.interactable; _targetId = _target.id; _fromHand = true; _anchor = InitialAnchor(carryingObject); Transform val = (((Object)(object)carryingObject.alternativePhysicsParent != (Object)null) ? carryingObject.alternativePhysicsParent : ((Component)carryingObject).transform); _euler = val.eulerAngles; _axis = 0; _active = true; Announce(); } catch (Exception ex) { ManualLogSource log = Plugin.Log2; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PlacementPlus] enter-from-hand failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } } private void HandleKeys() { //IL_0011: 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_004a: 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_0055: 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_007c: 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_006c: 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_0089: 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) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) float num = 0.1f; float num2 = 15f; bool key = Input.GetKey(PlacementConfig.CoarseMod.Value); bool key2 = Input.GetKey(PlacementConfig.FineMod.Value); if (key) { num = 0.3f; num2 = 45f; } else if (key2) { num = 0.01f; num2 = 1f; } Vector3 val = FlatForward(); Vector3 val2 = FlatRight(); if (Repeat(PlacementConfig.NudgeForward.Value)) { MoveAnchor(val * num); } if (Repeat(PlacementConfig.NudgeBack.Value)) { MoveAnchor(-val * num); } if (Repeat(PlacementConfig.NudgeRight.Value)) { MoveAnchor(val2 * num); } if (Repeat(PlacementConfig.NudgeLeft.Value)) { MoveAnchor(-val2 * num); } if (Repeat(PlacementConfig.NudgeUp.Value)) { MoveAnchor(Vector3.up * num); } if (Repeat(PlacementConfig.NudgeDown.Value)) { MoveAnchor(Vector3.down * num); } if (Repeat(PlacementConfig.RotateCCW.Value)) { RotateAxis(0f - num2); } if (Repeat(PlacementConfig.RotateCW.Value)) { RotateAxis(num2); } if (Input.GetKeyDown(PlacementConfig.CycleAxis.Value)) { _axis = (_axis + 1) % 3; ConfigEntry<bool> allowPitchRoll = PlacementConfig.AllowPitchRoll; if (allowPitchRoll != null && !allowPitchRoll.Value) { _axis = 0; } Plugin.Log2.LogInfo((object)("[PlacementPlus] rotation axis: " + AxisName())); } if (Input.GetKeyDown(PlacementConfig.Reset.Value)) { _euler = new Vector3(0f, Mathf.Round(_euler.y / 45f) * 45f, 0f); } if (Input.GetKeyDown(PlacementConfig.CopyRot.Value)) { CopiedEuler = _euler; Plugin.Log2.LogInfo((object)("[PlacementPlus] copied rotation " + V(_euler))); } if (Input.GetKeyDown(PlacementConfig.PasteRot.Value) && CopiedEuler.HasValue) { _euler = CopiedEuler.Value; Plugin.Log2.LogInfo((object)("[PlacementPlus] pasted rotation " + V(_euler))); } if (Input.GetKeyDown(PlacementConfig.Confirm.Value)) { Confirm(); } else if (Input.GetKeyDown(PlacementConfig.EnterKey.Value)) { Exit(placed: false); } } private void HandleFixtureNudge() { //IL_000d: 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_004a: 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_0086: 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) if (!Gate.TextOrPopupActive()) { float num = (Input.GetKey(PlacementConfig.CoarseMod.Value) ? 0.9f : 0.3f); if (Repeat(PlacementConfig.NudgeForward.Value)) { FixtureOffsetZ += num; } if (Repeat(PlacementConfig.NudgeBack.Value)) { FixtureOffsetZ -= num; } if (Repeat(PlacementConfig.NudgeRight.Value)) { FixtureOffsetX += num; } if (Repeat(PlacementConfig.NudgeLeft.Value)) { FixtureOffsetX -= num; } if (Input.GetKeyDown(PlacementConfig.Reset.Value)) { FixtureOffsetX = 0f; FixtureOffsetZ = 0f; } float num2 = Mathf.Max(1f, PlacementConfig.MaxDistance?.Value ?? 10f); FixtureOffsetZ = Mathf.Clamp(FixtureOffsetZ, -0.9f, num2); FixtureOffsetX = Mathf.Clamp(FixtureOffsetX, 0f - num2, num2); } } private void MoveAnchor(Vector3 delta) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_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) //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_004e: 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_005f: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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) _anchor += delta; try { Vector3 position = ((Component)Player.Instance.cam).transform.position; float num = Mathf.Max(1f, PlacementConfig.MaxDistance?.Value ?? 10f); Vector3 val = _anchor - position; if (((Vector3)(ref val)).magnitude > num) { _anchor = position + ((Vector3)(ref val)).normalized * num; } } catch { } } private void RotateAxis(float deg) { //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_0056: 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) Vector3 euler = _euler; bool flag = PlacementConfig.AllowPitchRoll?.Value ?? true; if (_axis == 0 || !flag) { euler.y += deg; } else if (_axis == 1) { euler.x += deg; } else { euler.z += deg; } _euler = euler; } private void Confirm() { //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: 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_01eb: 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_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown //IL_004c: 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_0056: 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) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_0087: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_ctrl == (Object)null || _target == null) { Exit(placed: false); return; } bool flag = default(bool); try { Transform val = (((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent : ((Component)_ctrl).transform); Quaternion val2 = Quaternion.Euler(_euler); val.SetPositionAndRotation(_anchor, val2); ConfigEntry<bool> surfaceClearance = PlacementConfig.SurfaceClearance; if (surfaceClearance == null || surfaceClearance.Value) { Vector3 val3 = ComputeClearance(_ctrl, _anchor); if (val3 != Vector3.zero) { _anchor += val3; val.SetPositionAndRotation(_anchor, val2); if (Verbose) { ManualLogSource log = Plugin.Log2; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(49, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] surface-clearance lifted "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(PresetName(_target)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" by "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(val3)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_anchor)); } log.LogWarning(val4); } } } ActionController.Instance.PutDown(_target, ((Actor)Player.Instance).currentNode, (Actor)(object)Player.Instance); val.SetPositionAndRotation(_anchor, val2); try { if ((Object)(object)_ctrl.rb != (Object)null) { _ctrl.rb.velocity = Vector3.zero; _ctrl.rb.angularVelocity = Vector3.zero; } } catch { } _ctrl.SetPhysics(false, (Actor)null); ((Behaviour)_ctrl).enabled = false; _target.MoveInteractable(_anchor, _euler, true); _target.SetSpawnPositionRelevent(true); val.SetPositionAndRotation(_anchor, val2); FrozenMark.SetFrozen(_target, _anchor, _euler); if (Verbose) { Vector3 v = (((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent.position : ((Component)_ctrl).transform.position); ManualLogSource log2 = Plugin.Log2; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(64, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] FROZE "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(PresetName(_target)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": anchor="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_anchor)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" euler="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_euler)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ctrlPos="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(((Component)_ctrl).transform.position)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" altParent="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(v)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" wPos="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_target.wPos)); } log2.LogWarning(val4); } Diag.DumpAnchors("FROZE", _target); Plugin.Log2.LogInfo((object)"[PlacementPlus] placed item at the previewed pose."); } catch (Exception ex) { ManualLogSource log3 = Plugin.Log2; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] confirm failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message); } log3.LogWarning(val4); } Exit(placed: true); } private void Exit(bool placed) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown bool fromHand = _fromHand; Interactable target = _target; _active = false; _target = null; _ctrl = null; _fromHand = false; _axis = 0; _targetId = -1; if (!(!placed && fromHand) || target == null) { return; } try { InteractableController val = (((Object)(object)InteractionController.Instance != (Object)null) ? InteractionController.Instance.carryingObject : null); if ((Object)(object)val != (Object)null) { val.DropThis(false); } FirstPersonItemController.Instance.PickUpItem(target, true, false, true, true, true); } catch (Exception ex) { ManualLogSource log = Plugin.Log2; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PlacementPlus] return-to-hand failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } } private bool Repeat(KeyCode k) { //IL_0006: 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) //IL_0014: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (Input.GetKeyDown(k)) { _repeatAt[k] = unscaledTime + 0.35f; return true; } if (Input.GetKey(k)) { if (!_repeatAt.TryGetValue(k, out var value)) { value = unscaledTime + 0.35f; } if (unscaledTime >= value) { _repeatAt[k] = unscaledTime + 0.05f; return true; } } return false; } private static Vector3 FlatForward() { //IL_000f: 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_0037: 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) Vector3 forward = ((Component)Player.Instance.cam).transform.forward; forward.y = 0f; if (!(((Vector3)(ref forward)).sqrMagnitude > 0.0001f)) { return Vector3.forward; } return ((Vector3)(ref forward)).normalized; } private static Vector3 FlatRight() { //IL_000f: 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_0037: 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) Vector3 right = ((Component)Player.Instance.cam).transform.right; right.y = 0f; if (!(((Vector3)(ref right)).sqrMagnitude > 0.0001f)) { return Vector3.right; } return ((Vector3)(ref right)).normalized; } private static Vector3 InitialAnchor(InteractableController co) { //IL_0011: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_0078: 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_0087: 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_0057: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = ((Component)Player.Instance.cam).transform; RaycastHit val = default(RaycastHit); if (Physics.Raycast(transform.position, transform.forward, ref val, 4f, Toolbox.Instance.heldObjectsObjectsLayerMask)) { float num = 0.05f; try { num = Mathf.Max(0.05f, co.colliderExtents.y); } catch { } return ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * num; } return transform.position + transform.forward * 1.5f; } catch { try { Transform transform2 = ((Component)Player.Instance.cam).transform; return transform2.position + transform2.forward * 1.5f; } catch { return Vector3.zero; } } } private Vector3 ComputeClearance(InteractableController ctrl, Vector3 anchor) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: 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) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Expected O, but got Unknown //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0