using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using LethalCompanyInputUtils.Api;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ShipCleaner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShipCleaner")]
[assembly: AssemblyTitle("ShipCleaner")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace ShipCleaner
{
[BepInPlugin("com.yakka_productions.shipcleaner", "ShipCleaner", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ShipCleaner : BaseUnityPlugin
{
internal static ManualLogSource Log;
private void Awake()
{
//IL_0030: 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_003b: Expected O, but got Unknown
//IL_003b: 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)
Log = ((BaseUnityPlugin)this).Logger;
ShipCleanerConfig.Init(((BaseUnityPlugin)this).Config);
Log.LogInfo((object)"ShipCleaner loaded.");
new ShipCleanerKeybinds();
GameObject val = new GameObject("ShipCleaner_Manager");
Object.DontDestroyOnLoad((Object)val);
((Object)val).hideFlags = (HideFlags)61;
val.AddComponent<ShipCleaner_Manager>();
val.AddComponent<ShipCleaner_HotkeyListener>();
Log.LogInfo((object)"ShipCleaner_Manager created.");
}
}
public enum SortingMode
{
ScrapToolsAndEquipment,
ScrapOnly,
ToolsAndEquipmentOnly
}
public static class ShipCleanerConfig
{
public static ConfigEntry<SortingMode> SortingModeConfig { get; private set; }
public static ConfigEntry<bool> UseStorageCloset { get; private set; }
public static bool ShouldSortScrap
{
get
{
if (SortingModeConfig.Value != 0)
{
return SortingModeConfig.Value == SortingMode.ScrapOnly;
}
return true;
}
}
public static bool ShouldSortTools
{
get
{
if (SortingModeConfig.Value != 0)
{
return SortingModeConfig.Value == SortingMode.ToolsAndEquipmentOnly;
}
return true;
}
}
public static bool SortToolsToCloset => UseStorageCloset.Value;
public static void Init(ConfigFile config)
{
SortingModeConfig = config.Bind<SortingMode>("General", "Sorting Mode", SortingMode.ScrapToolsAndEquipment, "Controls what ShipCleaner sorts when the hotkey is pressed.\n ScrapToolsAndEquipment — Sort everything (default).\n ScrapOnly — Only move scrap to the floor grid; leave tools untouched.\n ToolsAndEquipmentOnly — Only move tools/equipment; leave scrap untouched.");
UseStorageCloset = config.Bind<bool>("General", "Use Storage Closet", true, "When true, tools and equipment are sorted into the Storage Closet shelves (default).\nWhen false, tools and equipment are arranged on the floor along the closet's default wall,\nuseful for players who prefer floor-only organisation.");
if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
{
RegisterLethalConfigItems();
}
}
private static void RegisterLethalConfigItems()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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_002c: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem<SortingMode>(SortingModeConfig, new EnumDropDownOptions
{
Name = "Sorting Mode",
Description = "Choose what ShipCleaner sorts when the hotkey is pressed:\n\n• Scrap, Tools & Equipment — Sort everything (default).\n• Scrap Only — Only move scrap items to the floor grid.\n• Tools & Equipment Only — Only move tools/equipment to the closet or wall.",
RequiresRestart = false
}));
LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(UseStorageCloset, new BoolCheckBoxOptions
{
Name = "Use Storage Closet",
Description = "ON — Tools and equipment are sorted into the Storage Closet shelves (default).\nOFF — Tools and equipment are placed on the floor along the closet's default wall.\n Useful for players who prefer floor-only organisation.",
RequiresRestart = false
}));
}
}
public class ShipCleaner_HotkeyListener : MonoBehaviour
{
private void Update()
{
if (ShipCleanerKeybinds.Instance != null && ShipCleanerKeybinds.Instance.SortItemsKeyWasPressed)
{
ShipCleaner.Log.LogInfo((object)"Cleaning Ship");
ShipCleaner_Manager.Instance?.RunFullSort();
}
}
}
public class ShipCleaner_Manager : MonoBehaviour
{
private Transform _shipInterior;
private readonly List<GrabbableObject> _toolItems = new List<GrabbableObject>();
private readonly List<GrabbableObject> _scrapItems = new List<GrabbableObject>();
private float _floorWorldY = 0.3f;
private static readonly string[] ShelfNodeNames = new string[4] { "Cube (3)", "Cube (2)", "Cube (1)", "Cube" };
private const float ShelfItemSpacing = 0.28f;
private const int MaxShelfItems = 6;
private const float ShelfSurfaceCorrection = -0.05f;
private const int ClosetItemYRot = 180;
private const int MaxItemsPerRow = 4;
private const float OneHandedCellSize = 0.45f;
private const float TwoHandedCellSize = 0.85f;
private const float OneHandedRowSpacing = 0.5f;
private const float TwoHandedRowSpacing = 1f;
private const float ShipFloorCenterX = 0.2f;
private const float TwoHandedCenterX = 0.2f;
private const float TwoHandedStartZ = -8f;
private const float OneHandedStartZ = -6.77f;
private const int TwoHandedFloorYRot = 90;
private const int OneHandedFloorYRot = 0;
private const int FloorLayerMask = 268437761;
private const int OneHRowsPerCol = 7;
private const int OneHNumCols = 9;
private const int TwoHRowsPerCol = 4;
private const int TwoHNumCols = 3;
private static readonly (string name, float rx, float rz)[] FurniturePaths = new(string, float, float)[24]
{
("StorageCloset", 1.5f, 1f),
("Terminal", 1.2f, 0.8f),
("Bunkbeds", 1.5f, 1.2f),
("FileCabinet", 0.8f, 0.6f),
("LightSwitchContainer", 0.5f, 0.5f),
("Teleporter(Clone)", 0.8f, 0.8f),
("InverseTeleporter(Clone)", 0.8f, 0.8f),
("Shower(Clone)", 1f, 1f),
("DogHouse(Clone)", 1.2f, 1.2f),
("ChargingStationStorage(Clone)", 0.8f, 0.6f),
("FridgeContainer(Clone)", 1f, 0.8f),
("FishBowlContainer(Clone)", 0.6f, 0.6f),
("PumpkinUnlockableContainer(Clone)", 0.6f, 0.6f),
("ShipHorn(Clone)", 1.5f, 1.2f),
("MicrowaveContainer(Clone)", 0.8f, 0.7f),
("PlushiePJManContainer(Clone)", 0.9f, 0.9f),
("RecordPlayerContainer(Clone)", 1f, 1f),
("RomanticTable(Clone)", 1f, 1f),
("SignalTranslator(Clone)", 0.8f, 0.6f),
("SofaChairContainer(Clone)", 0.6f, 0.6f),
("Television(Clone)", 1f, 1f),
("Toilet(Clone)", 0.7f, 0.7f),
("Mirror(Clone)", 1f, 1f),
("ElectricChair(Clone)", 0.6f, 0.6f)
};
public static ShipCleaner_Manager Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)this);
return;
}
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
public void RunFullSort()
{
if (!GameNetworkManager.Instance.isHostingGame)
{
Debug.Log((object)"ShipCleaner: Not the host — skipping sort.");
return;
}
Debug.Log((object)"ShipCleaner: Cleaning the ship!");
GameObject obj = GameObject.Find("Environment/HangarShip");
_shipInterior = ((obj != null) ? obj.transform : null);
if ((Object)(object)_shipInterior == (Object)null)
{
Debug.Log((object)"ShipCleaner: Could not find Environment/HangarShip — aborting.");
return;
}
_floorWorldY = ResolveFloorY();
CollectAndClassifyItems();
if (ShipCleanerConfig.ShouldSortTools)
{
if (ShipCleanerConfig.SortToolsToCloset)
{
SortToolsIntoCloset();
}
else
{
SortToolsOnFloor();
}
}
if (ShipCleanerConfig.ShouldSortScrap)
{
SortScrapOnFloorGrid();
}
Debug.Log((object)"ShipCleaner: Ship has been cleaned!");
}
private float ResolveFloorY()
{
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: 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_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: 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_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
List<float> list = new List<float>();
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
foreach (GrabbableObject val in array)
{
if (val.isHeld)
{
continue;
}
bool flag = val.isInShipRoom;
if (!flag)
{
Vector3 val2 = _shipInterior.InverseTransformPoint(((Component)val).transform.position);
flag = Mathf.Abs(val2.x) < 15f && Mathf.Abs(val2.y) < 10f && Mathf.Abs(val2.z) < 15f;
}
if (flag)
{
float y = ((Component)val).transform.position.y;
if (!(y < -2f) && !(y > 3f) && !(((Component)val).transform.position.z < -14.5f))
{
list.Add(y);
}
}
}
if (list.Count > 0)
{
list.Sort();
return list[0];
}
RaycastHit val3 = default(RaycastHit);
if (Physics.Raycast(_shipInterior.position + Vector3.up * 20f, Vector3.down, ref val3, 40f, 268437761, (QueryTriggerInteraction)1))
{
return ((RaycastHit)(ref val3)).point.y;
}
return 0.3f;
}
private void CollectAndClassifyItems()
{
_toolItems.Clear();
_scrapItems.Clear();
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
foreach (GrabbableObject val in array)
{
if (!IsOnShip(val) || val.isHeld)
{
continue;
}
string text = (val.itemProperties?.itemName ?? ((Object)val).name).ToLowerInvariant();
if (!text.Contains("sticky note") && !text.Contains("clipboard") && !text.Contains("peeper") && !text.Contains("wheelbarrow") && !text.Contains("shopping cart") && !(text == "page") && !text.EndsWith(" page") && !text.EndsWith(" card") && !text.StartsWith("holofoil ") && !(text == "lethamon booster pack"))
{
if (IsTool(val))
{
_toolItems.Add(val);
}
else
{
_scrapItems.Add(val);
}
}
}
_toolItems.Sort(CompareItems);
_scrapItems.Sort(CompareItems);
}
private bool IsOnShip(GrabbableObject item)
{
//IL_0016: 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)
//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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (item.isInShipRoom)
{
return true;
}
Vector3 val = _shipInterior.InverseTransformPoint(((Component)item).transform.position);
if (Mathf.Abs(val.x) < 15f && Mathf.Abs(val.y) < 10f)
{
return Mathf.Abs(val.z) < 15f;
}
return false;
}
private bool IsTool(GrabbableObject item)
{
Item itemProperties = item.itemProperties;
if ((Object)(object)itemProperties == (Object)null)
{
return false;
}
string text = (itemProperties.itemName ?? ((Object)item).name).ToLowerInvariant();
if (text.Contains("flashlight") || text.Contains("key") || text.Contains("walkie") || text.Contains("portable teleporter") || text.Contains("advanced portable teleporter") || text.Contains("pokeball") || text.Contains("great ball") || text.Contains("ultra ball") || text.Contains("master ball") || text.Contains("shotgun") || text.Contains("ammo") || text.Contains("grenade") || text.Contains("flashbang") || text.Contains("zap") || text.Contains("stun") || text.Contains("rifle") || text.Contains("magazine") || text.Contains("belt") || text.Contains("spray") || text.Contains("weed") || text.Contains("tzp") || text.Contains("inhalant") || text.Contains("lockpicker") || text.Contains("whoopie") || text.Contains("diving kit") || text.Contains("helmet") || text.Contains("boombox") || text.Contains("ladder") || text.Contains("jetpack") || text.Contains("radar") || text.Contains("shovel"))
{
return true;
}
if (itemProperties.isScrap)
{
return false;
}
if (text.Contains("flashlight") || text.Contains("key") || text.Contains("walkie"))
{
return true;
}
if (text.Contains("shotgun") || text.Contains("ammo") || text.Contains("grenade") || text.Contains("flashbang") || text.Contains("zap") || text.Contains("stun") || text.Contains("rifle") || text.Contains("magazine"))
{
return true;
}
if (text.Contains("belt") || text.Contains("spray") || text.Contains("weed") || text.Contains("tzp") || text.Contains("inhalant") || text.Contains("lockpicker") || text.Contains("whoopie"))
{
return true;
}
if (text.Contains("boombox") || text.Contains("ladder") || text.Contains("jetpack") || text.Contains("radar") || text.Contains("shovel"))
{
return true;
}
return false;
}
private bool IsTwoHanded(GrabbableObject item)
{
if ((Object)(object)item.itemProperties != (Object)null)
{
return item.itemProperties.twoHanded;
}
return false;
}
private int CompareItems(GrabbableObject a, GrabbableObject b)
{
string strA = a.itemProperties?.itemName ?? StripClone(((Object)a).name);
string strB = b.itemProperties?.itemName ?? StripClone(((Object)b).name);
return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase);
}
private string StripClone(string name)
{
int num = name.IndexOf("(Clone)", StringComparison.Ordinal);
if (num < 0)
{
return name;
}
return name.Substring(0, num);
}
private int GetShelfIndexForTool(GrabbableObject item)
{
string text = (item.itemProperties?.itemName ?? ((Object)item).name).ToLowerInvariant();
if (text.Contains("flashlight") || text.Contains("key") || text.Contains("walkie") || text.Contains("portable teleporter") || text.Contains("advanced portable teleporter") || text.Contains("pokeball") || text.Contains("great ball") || text.Contains("ultra ball") || text.Contains("master ball"))
{
return 0;
}
if (text.Contains("belt") || text.Contains("spray") || text.Contains("weed") || text.Contains("tzp") || text.Contains("inhalant") || text.Contains("lockpicker") || text.Contains("whoopie"))
{
return 1;
}
if (text.Contains("shotgun") || text.Contains("ammo") || text.Contains("grenade") || text.Contains("flashbang") || text.Contains("zap") || text.Contains("stun") || text.Contains("rifle") || text.Contains("magazine"))
{
return 2;
}
return 3;
}
private void SortToolsIntoCloset()
{
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
//IL_01ec: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: 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_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0253: 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_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_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_026a: Unknown result type (might be due to invalid IL or missing references)
//IL_026f: 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_0281: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: 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)
if (_toolItems.Count == 0)
{
return;
}
GameObject val = GameObject.Find("Environment/HangarShip/StorageCloset");
if ((Object)(object)val == (Object)null)
{
Debug.Log((object)"ShipCleaner: StorageCloset not found — placing tools on floor grid.");
_scrapItems.InsertRange(0, _toolItems);
return;
}
Transform val2 = null;
Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
foreach (Transform val3 in componentsInChildren)
{
if (((Object)val3).name == "ObjectPlacements")
{
val2 = val3;
break;
}
}
if ((Object)(object)val2 == (Object)null)
{
Debug.Log((object)"ShipCleaner: ObjectPlacements not found — placing tools on floor grid.");
_scrapItems.InsertRange(0, _toolItems);
return;
}
Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>();
foreach (Transform item in val2)
{
Transform val4 = item;
dictionary[((Object)val4).name] = val4;
}
Dictionary<int, List<GrabbableObject>> dictionary2 = new Dictionary<int, List<GrabbableObject>>();
for (int j = 0; j < ShelfNodeNames.Length; j++)
{
dictionary2[j] = new List<GrabbableObject>();
}
foreach (GrabbableObject toolItem in _toolItems)
{
dictionary2[GetShelfIndexForTool(toolItem)].Add(toolItem);
}
List<GrabbableObject> list = new List<GrabbableObject>();
foreach (KeyValuePair<int, List<GrabbableObject>> item2 in dictionary2)
{
List<GrabbableObject> value = item2.Value;
if (value.Count == 0)
{
continue;
}
string text = ShelfNodeNames[item2.Key];
if (!dictionary.TryGetValue(text, out var value2))
{
Debug.Log((object)("ShipCleaner: Shelf node '" + text + "' not found — overflowing to floor."));
list.AddRange(value);
continue;
}
int num = Mathf.Min(value.Count, 6);
float num2 = 0.28f * (float)(num - 1);
Vector3 val5 = val2.TransformDirection(Vector3.right);
Vector3 normalized = ((Vector3)(ref val5)).normalized;
Vector3 back = Vector3.back;
float num3 = 0.12f;
for (int k = 0; k < num; k++)
{
float num4 = value[k].itemProperties?.verticalOffset ?? 0f;
float num5 = (0f - num2) * 0.5f + (float)k * 0.28f;
Vector3 worldPos = value2.position + normalized * num5 + back * num3 + Vector3.up * (num4 + -0.05f);
int yRot = ((item2.Key == 3) ? 180 : ((item2.Key != 0) ? 90 : 0));
string text2 = (value[k].itemProperties?.itemName ?? ((Object)value[k]).name).ToLowerInvariant();
if (text2.Contains("rifle"))
{
yRot = 0;
}
else if (text2.Contains("magazine"))
{
yRot = 90;
}
MoveItem(value[k], worldPos, yRot);
}
if (value.Count > 6)
{
list.AddRange(value.Skip(6));
}
}
if (list.Count > 0)
{
_scrapItems.InsertRange(0, list);
}
}
private void SortToolsOnFloor()
{
//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_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
if (_toolItems.Count == 0)
{
return;
}
List<(Vector3, float, float)> zones = BuildAvoidanceZones();
int num = Mathf.RoundToInt(14f) + 1;
int num2 = 0;
RaycastHit val = default(RaycastHit);
Vector3 worldPos = default(Vector3);
foreach (GrabbableObject toolItem in _toolItems)
{
for (int i = 0; i < 50; i++)
{
int num3 = num2 % num;
int num4 = num2 / num;
float worldX = -5f + (float)num3 * 0.5f;
float worldZ = -12.5f - (float)num4 * 0.5f;
if (!IsCellBlocked(worldX, worldZ, zones) && !IsCellElevated(worldX, worldZ, _floorWorldY))
{
break;
}
num2++;
}
int num5 = num2 % num;
int num6 = num2 / num;
float num7 = -5f + (float)num5 * 0.5f;
float num8 = -12.5f - (float)num6 * 0.5f;
float num9 = toolItem.itemProperties?.verticalOffset ?? 0f;
if (Physics.Raycast(new Vector3(num7, _floorWorldY + 2f, num8), Vector3.down, ref val, 5f, 268437761, (QueryTriggerInteraction)1))
{
worldPos = ((RaycastHit)(ref val)).point + Vector3.up * num9;
}
else
{
((Vector3)(ref worldPos))..ctor(num7, _floorWorldY + num9, num8);
}
MoveItem(toolItem, worldPos, 0);
num2++;
}
}
private static float CellToWorldX(int cellIndex, bool isTwoHanded, float oneHStartX, float twoHStartX)
{
if (!isTwoHanded)
{
int num = cellIndex / 7 % 9;
return oneHStartX - (float)num * 1f;
}
int num2 = cellIndex / 4 % 3;
return twoHStartX - (float)num2 * 1f;
}
private static float CellToWorldZ(int cellIndex, bool isTwoHanded, float oneHStartZ, float twoHStartZ)
{
if (!isTwoHanded)
{
int num = cellIndex % 7;
return oneHStartZ - (float)num * 0.5f;
}
int num2 = cellIndex % 4;
return twoHStartZ + (float)num2 * 1f;
}
private List<(Vector3 pos, float rx, float rz)> BuildAvoidanceZones()
{
//IL_0080: 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_0087: 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_0096: Unknown result type (might be due to invalid IL or missing references)
GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (!dictionary.ContainsKey(((Object)val).name))
{
dictionary[((Object)val).name] = val;
}
}
List<(Vector3, float, float)> list = new List<(Vector3, float, float)>();
(string, float, float)[] furniturePaths = FurniturePaths;
for (int i = 0; i < furniturePaths.Length; i++)
{
var (key, item, item2) = furniturePaths[i];
if (dictionary.TryGetValue(key, out var value))
{
Vector3 position = value.transform.position;
if (!(position == Vector3.zero))
{
list.Add((position, item, item2));
}
}
}
return list;
}
private bool IsCellBlocked(float worldX, float worldZ, List<(Vector3 pos, float rx, float rz)> zones)
{
//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_0025: 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)
foreach (var (val, num, num2) in zones)
{
if (Mathf.Abs(worldX - val.x) < num && Mathf.Abs(worldZ - val.z) < num2)
{
return true;
}
}
return false;
}
private bool IsCellElevated(float worldX, float worldZ, float floorY)
{
//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_0029: Unknown result type (might be due to invalid IL or missing references)
RaycastHit val = default(RaycastHit);
if (Physics.Raycast(new Vector3(worldX, floorY + 3f, worldZ), Vector3.down, ref val, 5f, 268437761, (QueryTriggerInteraction)1))
{
return ((RaycastHit)(ref val)).point.y > floorY + 0.15f;
}
return false;
}
private void SortScrapOnFloorGrid()
{
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: 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_02f5: 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_032c: Unknown result type (might be due to invalid IL or missing references)
//IL_0333: Unknown result type (might be due to invalid IL or missing references)
//IL_033a: Unknown result type (might be due to invalid IL or missing references)
//IL_0347: Unknown result type (might be due to invalid IL or missing references)
//IL_034c: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
//IL_0317: Unknown result type (might be due to invalid IL or missing references)
//IL_031e: Unknown result type (might be due to invalid IL or missing references)
//IL_0323: Unknown result type (might be due to invalid IL or missing references)
//IL_0328: Unknown result type (might be due to invalid IL or missing references)
//IL_0367: Unknown result type (might be due to invalid IL or missing references)
//IL_036c: 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_0378: Unknown result type (might be due to invalid IL or missing references)
//IL_037d: Unknown result type (might be due to invalid IL or missing references)
//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
if (_scrapItems.Count == 0)
{
return;
}
List<GrabbableObject> list = (from i in _scrapItems.Where(delegate(GrabbableObject i)
{
string text2 = (i.itemProperties?.itemName ?? ((Object)i).name).ToLowerInvariant();
return text2.Contains("yield") || text2.Contains("stop sign");
})
orderby i.itemProperties?.itemName ?? ((Object)i).name
select i).ToList();
float[] array = new float[3] { -13f, -14f, -15f };
RaycastHit val = default(RaycastHit);
Vector3 worldPos = default(Vector3);
for (int j = 0; j < list.Count && j < array.Length; j++)
{
float num = list[j].itemProperties?.verticalOffset ?? 0f;
if (Physics.Raycast(new Vector3(9f, _floorWorldY + 2f, array[j]), Vector3.down, ref val, 5f, 268437761, (QueryTriggerInteraction)1))
{
worldPos = ((RaycastHit)(ref val)).point + Vector3.up * num;
}
else
{
((Vector3)(ref worldPos))..ctor(9f, _floorWorldY + num, array[j]);
}
MoveItem(list[j], worldPos, 0);
}
_scrapItems.RemoveAll(delegate(GrabbableObject i)
{
string text = (i.itemProperties?.itemName ?? ((Object)i).name).ToLowerInvariant();
return text.Contains("yield") || text.Contains("stop sign");
});
List<(Vector3, float, float)> zones = BuildAvoidanceZones();
List<IGrouping<string, GrabbableObject>> list2 = (from i in _scrapItems
group i by i.itemProperties?.itemName ?? StripClone(((Object)i).name) into g
orderby g.Max((GrabbableObject i) => i.scrapValue) descending
select g).ToList();
int num2 = 0;
int num3 = 0;
Vector3 val2 = default(Vector3);
RaycastHit val3 = default(RaycastHit);
Vector3 worldPos2 = default(Vector3);
RaycastHit val4 = default(RaycastHit);
foreach (IGrouping<string, GrabbableObject> item in list2)
{
List<GrabbableObject> list3 = item.OrderByDescending((GrabbableObject i) => i.scrapValue).ToList();
bool flag = IsTwoHanded(list3[0]);
int num4 = (flag ? 90 : 0);
Random random = new Random(((object)list3[0]).GetHashCode());
for (int k = 0; k < list3.Count; k++)
{
int num5 = k / 6;
int num6 = k % 6;
int num7 = (flag ? num3 : num2) + num5;
for (int l = 0; l < 50; l++)
{
float worldX = CellToWorldX(num7, flag, 6f, -3f);
float worldZ = CellToWorldZ(num7, flag, -13f, -16f);
if (!IsCellBlocked(worldX, worldZ, zones) && !IsCellElevated(worldX, worldZ, _floorWorldY))
{
break;
}
num7++;
}
float num8 = CellToWorldX(num7, flag, 6f, -3f);
float num9 = CellToWorldZ(num7, flag, -13f, -16f);
((Vector3)(ref val2))..ctor(num8, _floorWorldY + 2f, num9);
float num10 = list3[k].itemProperties?.verticalOffset ?? 0f;
if (Physics.Raycast(val2, Vector3.down, ref val3, 5f, 268437761, (QueryTriggerInteraction)1))
{
worldPos2 = ((RaycastHit)(ref val3)).point + Vector3.up * num10;
}
else if (Physics.Raycast(new Vector3(val2.x, val2.y, val2.z + 0.5f), Vector3.down, ref val4, 5f, 268437761, (QueryTriggerInteraction)1))
{
worldPos2 = ((RaycastHit)(ref val4)).point + Vector3.up * num10;
}
else
{
((Vector3)(ref worldPos2))..ctor(num8, _floorWorldY + num10, num9);
}
int yRot = num4 + ((num6 != 0) ? random.Next(-15, 16) : 0);
if (list3[k].itemProperties?.itemName == null)
{
_ = ((Object)list3[k]).name;
}
MoveItem(list3[k], worldPos2, yRot);
}
int num11 = Mathf.CeilToInt((float)list3.Count / 6f);
if (flag)
{
num3 += num11;
}
else
{
num2 += num11;
}
}
}
private void MoveItem(GrabbableObject item, Vector3 worldPos, int yRot)
{
//IL_002c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: 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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: 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_0094: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
return;
}
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if (!((Object)(object)val == (Object)null))
{
Vector3 val2 = (item.targetFloorPosition = _shipInterior.InverseTransformPoint(worldPos));
((Component)item).transform.position = worldPos;
((Component)item).transform.rotation = Quaternion.Euler(0f, (float)yRot, 0f);
item.fallTime = 1f;
val.SetObjectAsNoLongerHeld(true, true, val2, item, yRot);
Rigidbody component = ((Component)item).GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
component.velocity = Vector3.zero;
component.angularVelocity = Vector3.zero;
component.isKinematic = true;
((MonoBehaviour)this).StartCoroutine(ReEnablePhysics(component));
}
}
}
private IEnumerator ReEnablePhysics(Rigidbody rb)
{
yield return (object)new WaitForFixedUpdate();
if ((Object)(object)rb != (Object)null)
{
rb.isKinematic = false;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
}
}
public class ShipCleanerKeybinds : LcInputActions
{
public static ShipCleanerKeybinds Instance { get; private set; }
[InputAction("<Keyboard>/comma")]
public InputAction SortItemsKey { get; private set; }
public bool SortItemsKeyWasPressed
{
get
{
if (SortItemsKey != null)
{
return SortItemsKey.triggered;
}
return false;
}
}
public ShipCleanerKeybinds()
{
Instance = this;
}
}
}