using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using OptimalScrapsOrganization.Patches;
using OptimalScrapsOrganization.Scripts;
using StaticNetcodeLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShipScrapReorder")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("ShipScrapReorder")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4a2e00b2b5baa2a23657ebd7194937b9ed8ee747")]
[assembly: AssemblyProduct("ShipScrapReorder")]
[assembly: AssemblyTitle("ShipScrapReorder")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 OptimalScrapsOrganization
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("wexop.ship_item_reorder", "ShipScrapReorder", "1.0.4")]
public class OptimalScrapsOrganizationPlugin : BaseUnityPlugin
{
public const string GUID = "wexop.ship_item_reorder";
public const string NAME = "ShipScrapReorder";
public const string VERSION = "1.0.4";
public bool hasPatchedStartTerminal;
public ConfigEntry<float> distanceBetweenScraps;
public ConfigEntry<float> rotationBetweenScraps;
public ConfigEntry<int> organiseDefaultValueRange;
public ConfigEntry<bool> autoReorderOnLeftMoon;
public ConfigEntry<bool> rotateScraps;
public ConfigEntry<bool> orderShopItems;
public ConfigEntry<bool> orderPlacedItems;
public ConfigEntry<bool> hideHelpMessage;
public ConfigEntry<string> exclusionList;
public ConfigEntry<OrganizeBy> defaultReorderType;
public static OptimalScrapsOrganizationPlugin instance;
private void Awake()
{
instance = this;
((BaseUnityPlugin)this).Logger.LogInfo((object)"OptimalScrapsOrganization starting....");
LoadConfig();
Harmony.CreateAndPatchAll(typeof(PatchTerminal), (string)null);
Harmony.CreateAndPatchAll(typeof(PatchStartOfRound), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"OptimalScrapsOrganization Patched !!");
}
private void LoadConfig()
{
exclusionList = ((BaseUnityPlugin)this).Config.Bind<string>("General", "exclusionList", "clipboard,stickynote", "List of items not affected by reorder. Example : shovel,airhorn. No need to restart the game :)");
CreateStringConfig(exclusionList);
distanceBetweenScraps = ((BaseUnityPlugin)this).Config.Bind<float>("General", "distanceBetweenScraps", 1.1f, "Distance between each stacks of scraps. No need to restart the game :)");
CreateFloatConfig(distanceBetweenScraps, 0f, 5f);
organiseDefaultValueRange = ((BaseUnityPlugin)this).Config.Bind<int>("General", "organiseDefaultValueRange", 20, "Distance between each stacks of objects. No need to restart the game :)");
CreateIntConfig(organiseDefaultValueRange, 1, 200);
defaultReorderType = ((BaseUnityPlugin)this).Config.Bind<OrganizeBy>("General", "defaultReorderType", OrganizeBy.VALUE, "Default reorder type. No need to restart the game :)");
CreateOrganiseByConfig(defaultReorderType);
autoReorderOnLeftMoon = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "autoReorderOnLeftMoon", true, "Auto reorder scraps when leaving the moon. No need to restart the game :)");
CreateBoolConfig(autoReorderOnLeftMoon);
rotateScraps = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "rotateScraps", true, "Rotate scraps so you can see how many of them are in a stack. No need to restart the game :)");
CreateBoolConfig(rotateScraps);
rotationBetweenScraps = ((BaseUnityPlugin)this).Config.Bind<float>("General", "rotationBetweenScraps", 10f, "Rotate scraps so you can see how many of them are in a stack. No need to restart the game :)");
CreateFloatConfig(rotationBetweenScraps);
orderShopItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "orderShopItems", true, "Reorder affect shop items (flashlights, shovel, jetpack...). No need to restart the game :)");
CreateBoolConfig(orderShopItems);
orderPlacedItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "orderPlacedItems", true, "Reorder placed items, for example in locker. No need to restart the game :)");
CreateBoolConfig(orderPlacedItems);
hideHelpMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "hideHelpMessage", false, "Hide help command message. No need to restart the game :)");
CreateBoolConfig(hideHelpMessage);
}
private void CreateFloatConfig(ConfigEntry<float> configEntry, float min = 0f, float max = 100f)
{
//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_000e: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
FloatSliderOptions val = new FloatSliderOptions();
((BaseRangeOptions<float>)val).Min = min;
((BaseRangeOptions<float>)val).Max = max;
((BaseOptions)val).RequiresRestart = false;
FloatSliderConfigItem val2 = new FloatSliderConfigItem(configEntry, val);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
}
private void CreateIntConfig(ConfigEntry<int> configEntry, int min = 0, int max = 100)
{
//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_000e: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
IntSliderOptions val = new IntSliderOptions();
((BaseRangeOptions<int>)val).Min = min;
((BaseRangeOptions<int>)val).Max = max;
((BaseOptions)val).RequiresRestart = false;
IntSliderConfigItem val2 = new IntSliderConfigItem(configEntry, val);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
}
private void CreateStringConfig(ConfigEntry<string> configEntry)
{
//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_0014: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
TextInputFieldConfigItem val = new TextInputFieldConfigItem(configEntry, new TextInputFieldOptions
{
RequiresRestart = false
});
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
private void CreateBoolConfig(ConfigEntry<bool> configEntry)
{
//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_0014: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
BoolCheckBoxConfigItem val = new BoolCheckBoxConfigItem(configEntry, new BoolCheckBoxOptions
{
RequiresRestart = false
});
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
private void CreateOrganiseByConfig(ConfigEntry<OrganizeBy> configEntry)
{
EnumDropDownConfigItem<OrganizeBy> val = new EnumDropDownConfigItem<OrganizeBy>(configEntry, false);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
public bool StringContain(string name, string verifiedName)
{
string text = name.ToLower();
while (text.Contains(" "))
{
text = text.Replace(" ", "");
}
string text2 = verifiedName.ToLower();
while (text2.Contains(" "))
{
text2 = text2.Replace(" ", "");
}
return text.Contains(text2);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "ShipScrapReorder";
public const string PLUGIN_NAME = "ShipScrapReorder";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace OptimalScrapsOrganization.Scripts
{
public enum OrganizeBy
{
VALUE,
NAME,
TYPE
}
[StaticNetcode]
public class NetworkOrganization
{
[ServerRpc]
public static void OrganizeScrapsServerRpc(OrganizeInformation organizeInformation)
{
OrganizeScrapsClientRpc(organizeInformation);
}
[ClientRpc]
public static void OrganizeScrapsClientRpc(OrganizeInformation organizeInformation)
{
ScrapsOrganizationManager.OrganizeShipScraps(organizeInformation);
}
}
public class OrganizeInformation
{
public OrganizeBy OrganizeBy;
public int value;
public float distanceBetweenObjects;
public bool rotateScraps;
public float rotationBetweenScraps;
public string exclusionList;
public bool orderShopItems;
public bool orderPlacedItems;
}
public class ScrapsOrganizationManager
{
public static Vector3 position = new Vector3(-6.1846676f, 0.10327625f, -5f);
public static Vector3 maxPosition = new Vector3(9.047635f, 0f, -5f);
public static Vector3 postionRight = new Vector3(-4.263417f, 0f, -9.5f);
public static Vector3 maxPostionRight = new Vector3(3.728537f, 0f, -9.5f);
public static Transform HangarShipTransform => StartOfRound.Instance.elevatorTransform;
public static bool IsScrap(GrabbableObject grabbableObject, OrganizeInformation organizeInformation)
{
if ((Object)(object)grabbableObject == (Object)null)
{
return false;
}
if (!IsScrap(grabbableObject.itemProperties, organizeInformation))
{
return false;
}
if (grabbableObject.isHeld || !grabbableObject.grabbable || IsExcluded(grabbableObject, organizeInformation))
{
return false;
}
return true;
}
public static bool IsExcluded(GrabbableObject grabbableObject, OrganizeInformation organizeInformation)
{
bool result = false;
if (organizeInformation.exclusionList == "")
{
return false;
}
organizeInformation.exclusionList.Split(",").ToList().ForEach(delegate(string name)
{
if (organizeInformation.exclusionList == "")
{
result = false;
}
else if (OptimalScrapsOrganizationPlugin.instance.StringContain(grabbableObject.itemProperties.itemName, name.ToString()))
{
result = true;
}
});
return result;
}
public static bool IsScrap(Item item, OrganizeInformation organizeInformation)
{
if ((Object)(object)item == (Object)null)
{
return false;
}
return organizeInformation.orderShopItems || item.isScrap;
}
public static bool IsValidScrap(GrabbableObject grabbableObject, OrganizeInformation organizeInformation)
{
if ((Object)(object)grabbableObject == (Object)null)
{
return false;
}
if (!IsScrap(grabbableObject, organizeInformation))
{
return false;
}
return true;
}
private static List<GrabbableObject> GetValidScrap(IEnumerable<GrabbableObject> grabbableObjects, OrganizeInformation organizeInformation)
{
if (grabbableObjects == null)
{
return new List<GrabbableObject>();
}
return grabbableObjects.Where((GrabbableObject x) => IsValidScrap(x, organizeInformation)).ToList();
}
public static List<GrabbableObject> GetScrapFromShip(OrganizeInformation organizeInformation)
{
if ((Object)(object)HangarShipTransform == (Object)null)
{
return new List<GrabbableObject>();
}
return GetValidScrap(((Component)HangarShipTransform).GetComponentsInChildren<GrabbableObject>(), organizeInformation);
}
public static void OrganizeShipScraps(OrganizeInformation organizeInformation)
{
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
List<GrabbableObject> scrapsOnShip = GetScrapFromShip(organizeInformation);
int value = organizeInformation.value;
OrganizeBy organizeBy = organizeInformation.OrganizeBy;
if (value <= 0)
{
value = 1;
}
switch (organizeBy)
{
case OrganizeBy.VALUE:
scrapsOnShip.Sort((GrabbableObject x, GrabbableObject y) => x.scrapValue.CompareTo(y.scrapValue));
break;
case OrganizeBy.NAME:
scrapsOnShip.Sort((GrabbableObject x, GrabbableObject y) => x.itemProperties.itemName.CompareTo(y.itemProperties.itemName));
break;
case OrganizeBy.TYPE:
scrapsOnShip.Sort((GrabbableObject x, GrabbableObject y) => x.itemProperties.twoHanded.CompareTo(y.itemProperties.twoHanded));
break;
}
if (scrapsOnShip.Count == 0)
{
return;
}
Vector3 basePos = position;
Vector3 usePostion = basePos;
int valueRange = 0;
float rotation = 0f;
for (; valueRange < scrapsOnShip[0].scrapValue; valueRange += value)
{
}
int index = -1;
scrapsOnShip.ForEach(delegate(GrabbableObject scrap)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0318: Unknown result type (might be due to invalid IL or missing references)
//IL_031d: 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)
index++;
if (!((Object)(object)scrap == (Object)null) && (organizeInformation.orderPlacedItems || !((Object)(object)((Component)scrap).transform.parent != (Object)(object)HangarShipTransform)))
{
if (usePostion.z < maxPostionRight.z)
{
usePostion = position;
}
if (usePostion.x > maxPosition.x)
{
basePos += new Vector3(0f, 0f, 0f - organizeInformation.distanceBetweenObjects);
usePostion = basePos;
}
scrap.targetFloorPosition = usePostion;
((Component)scrap).transform.eulerAngles = Vector3.zero + scrap.itemProperties.restingRotation;
((Component)scrap).transform.parent = HangarShipTransform;
if (Object.op_Implicit((Object)(object)((scrap != null) ? ((Component)scrap).transform.parent : null)))
{
Debug.Log((object)(((scrap != null) ? ((Object)((Component)scrap).transform.parent).name : null) + " IS TRANSFORM PARENT NAME"));
}
if (organizeInformation.rotateScraps)
{
Transform transform = ((Component)scrap).transform;
transform.eulerAngles += new Vector3(0f, rotation, 0f);
rotation += organizeInformation.rotationBetweenScraps;
}
if ((organizeBy != OrganizeBy.NAME || index >= scrapsOnShip.Count - 1 || !(scrap.itemProperties.itemName == scrapsOnShip[index + 1].itemProperties.itemName)) && (organizeBy != 0 || index >= scrapsOnShip.Count - 1 || scrapsOnShip[index + 1].scrapValue > valueRange) && (organizeBy != OrganizeBy.TYPE || index >= scrapsOnShip.Count - 1 || scrapsOnShip[index + 1].itemProperties.twoHanded != scrap.itemProperties.twoHanded))
{
if (index < scrapsOnShip.Count - 1)
{
for (; valueRange < scrapsOnShip[index + 1].scrapValue; valueRange += value)
{
}
}
usePostion += new Vector3(organizeInformation.distanceBetweenObjects, 0f, 0f);
rotation = 0f;
}
}
});
}
}
}
namespace OptimalScrapsOrganization.Patches
{
[HarmonyPatch(typeof(StartOfRound))]
public class PatchStartOfRound
{
[HarmonyPatch("AutoSaveShipData")]
[HarmonyPrefix]
private static void ShipHasLeftPostfix(StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsServer && OptimalScrapsOrganizationPlugin.instance.autoReorderOnLeftMoon.Value)
{
OrganizeInformation organizeInformation = new OrganizeInformation();
organizeInformation.OrganizeBy = OptimalScrapsOrganizationPlugin.instance.defaultReorderType.Value;
organizeInformation.value = OptimalScrapsOrganizationPlugin.instance.organiseDefaultValueRange.Value;
organizeInformation.distanceBetweenObjects = OptimalScrapsOrganizationPlugin.instance.distanceBetweenScraps.Value;
organizeInformation.rotateScraps = OptimalScrapsOrganizationPlugin.instance.rotateScraps.Value;
organizeInformation.rotationBetweenScraps = OptimalScrapsOrganizationPlugin.instance.rotationBetweenScraps.Value;
organizeInformation.exclusionList = OptimalScrapsOrganizationPlugin.instance.exclusionList.Value;
organizeInformation.orderShopItems = OptimalScrapsOrganizationPlugin.instance.orderShopItems.Value;
organizeInformation.orderPlacedItems = OptimalScrapsOrganizationPlugin.instance.orderPlacedItems.Value;
NetworkOrganization.OrganizeScrapsClientRpc(organizeInformation);
}
}
}
[HarmonyPatch(typeof(Terminal))]
public class PatchTerminal
{
[HarmonyPatch("ParsePlayerSentence")]
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool ParsePlayerSentencePatch(Terminal __instance, ref TerminalNode __result)
{
string[] array = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (array[0].ToLower().Contains("reorder") || array[0].ToLower().Contains("reoder"))
{
if (array.Length > 1 && array[1].ToLower().Contains("help"))
{
__result = CreateTerminalNode("Commands :\n\n- reorder\n\n- reorder <valueRange>\n\n- reorder name\n\n- reorder type\n\n");
return false;
}
OrganizeBy organizeBy = OptimalScrapsOrganizationPlugin.instance.defaultReorderType.Value;
int result = OptimalScrapsOrganizationPlugin.instance.organiseDefaultValueRange.Value;
if (array.Length > 1 && array[1].ToLower().Contains("name"))
{
organizeBy = OrganizeBy.NAME;
}
else if (array.Length > 1 && array[1].ToLower().Contains("type"))
{
organizeBy = OrganizeBy.TYPE;
}
else if (array.Length > 1)
{
organizeBy = OrganizeBy.VALUE;
int.TryParse(array[1], out result);
}
OrganizeInformation organizeInformation = new OrganizeInformation();
organizeInformation.OrganizeBy = organizeBy;
organizeInformation.value = result;
organizeInformation.distanceBetweenObjects = OptimalScrapsOrganizationPlugin.instance.distanceBetweenScraps.Value;
organizeInformation.rotateScraps = OptimalScrapsOrganizationPlugin.instance.rotateScraps.Value;
organizeInformation.rotationBetweenScraps = OptimalScrapsOrganizationPlugin.instance.rotationBetweenScraps.Value;
organizeInformation.exclusionList = OptimalScrapsOrganizationPlugin.instance.exclusionList.Value;
organizeInformation.orderShopItems = OptimalScrapsOrganizationPlugin.instance.orderShopItems.Value;
organizeInformation.orderPlacedItems = OptimalScrapsOrganizationPlugin.instance.orderPlacedItems.Value;
NetworkOrganization.OrganizeScrapsServerRpc(organizeInformation);
__result = CreateTerminalNode("Done !");
return false;
}
return true;
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void StartPatch(ref TerminalNodesList ___terminalNodes)
{
if (!OptimalScrapsOrganizationPlugin.instance.hasPatchedStartTerminal && !OptimalScrapsOrganizationPlugin.instance.hideHelpMessage.Value)
{
int index = 1;
string displayText = ___terminalNodes.specialNodes[index].displayText;
string displayText2 = (displayText += "\n[ShipScrapReorder]\nType \"reorder help\" for a list of commands.\n");
___terminalNodes.specialNodes[index].displayText = displayText2;
index = 13;
displayText = ___terminalNodes.specialNodes[index].displayText;
displayText2 = (displayText += "\n\n>REORDER HELP\nTo see the list of ShipScrapReorder commands.\n");
___terminalNodes.specialNodes[index].displayText = displayText2;
OptimalScrapsOrganizationPlugin.instance.hasPatchedStartTerminal = true;
}
}
public static TerminalNode CreateTerminalNode(string message, bool clearPreviousText = true, int maxChar = 50)
{
TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
val.displayText = message;
val.clearPreviousText = clearPreviousText;
val.maxCharactersToType = maxChar;
return val;
}
}
}