Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Scifi Box v1.0.1
BepInEx/plugins/ScifiBox/ScifiBox.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using CustomItemBehaviourLibrary.AbstractItems; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalLib.Extras; using LethalLib.Modules; using Microsoft.CodeAnalysis; using ScifiBox.Behaviour; using ScifiBox.Compat; using ScifiBox.Input; using ScifiBox.Misc; using ScifiBox.NetcodePatcher; using ScifiBox.Util; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; [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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } 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; } } [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 ScifiBox { [BepInPlugin("com.github.WhiteSpike.ScifiBox", "ScifiBox", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static readonly Harmony harmony = new Harmony("com.github.WhiteSpike.ScifiBox"); internal static readonly ManualLogSource mls = Logger.CreateLogSource("ScifiBox"); public static PluginConfig Config; private void Awake() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) IEnumerable<Type> enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item2 in enumerable) { MethodInfo[] methods = item2.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } Config = new PluginConfig(((BaseUnityPlugin)this).Config); string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "whitespike.scifibox"); AssetBundle val = AssetBundle.LoadFromFile(text); string text2 = "Assets/Sci-Fi Box/"; Item val2 = ScriptableObject.CreateInstance<Item>(); ((Object)val2).name = "ScifiBoxItemProperties"; val2.allowDroppingAheadOfPlayer = SyncedEntry<bool>.op_Implicit(Config.DROP_AHEAD_PLAYER); val2.canBeGrabbedBeforeGameStart = SyncedEntry<bool>.op_Implicit(Config.GRABBED_BEFORE_START); val2.canBeInspected = false; val2.creditsWorth = SyncedEntry<int>.op_Implicit(Config.PRICE); val2.floorYOffset = 0; val2.restingRotation = new Vector3(0f, 0f, 0f); val2.rotationOffset = new Vector3(0f, 0f, 0f); val2.positionOffset = new Vector3(0f, 0f, 0f); val2.verticalOffset = 0.2f; val2.weight = 0.99f + (float)SyncedEntry<int>.op_Implicit(Config.WEIGHT) / 100f; val2.minValue = SyncedEntry<int>.op_Implicit(Config.MINIMUM_VALUE); val2.maxValue = SyncedEntry<int>.op_Implicit(Config.MAXIMUM_VALUE); val2.isScrap = false; val2.twoHanded = true; val2.itemIcon = val.LoadAsset<Sprite>(text2 + "Icon.png"); val2.spawnPrefab = val.LoadAsset<GameObject>(text2 + "ScifiBox.prefab"); val2.spawnPrefab.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f); val2.dropSFX = val.LoadAsset<AudioClip>(text2 + "Drop.ogg"); val2.grabSFX = val.LoadAsset<AudioClip>(text2 + "Grab.ogg"); val2.pocketSFX = val.LoadAsset<AudioClip>(text2 + "Pocket.ogg"); val2.throwSFX = val.LoadAsset<AudioClip>(text2 + "Throw.ogg"); val2.highestSalePercentage = SyncedEntry<int>.op_Implicit(Config.HIGHEST_SALE_PERCENTAGE); val2.itemName = "Sci-fi Box"; val2.itemSpawnsOnGround = true; val2.isConductiveMetal = SyncedEntry<bool>.op_Implicit(Config.CONDUCTIVE); val2.requiresBattery = false; val2.batteryUsage = 0f; val2.twoHandedAnimation = true; val2.grabAnim = "HoldJetpack"; ScifiBoxBehaviour scifiBoxBehaviour = val2.spawnPrefab.AddComponent<ScifiBoxBehaviour>(); ((GrabbableObject)scifiBoxBehaviour).itemProperties = val2; ((GrabbableObject)scifiBoxBehaviour).grabbable = true; ((GrabbableObject)scifiBoxBehaviour).grabbableToEnemies = true; Utilities.FixMixerGroups(val2.spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(val2.spawnPrefab); Item item = ScriptableObject.CreateInstance<Item>(); ((Object)item).name = "ScrapScifiBoxItemProperties"; item.allowDroppingAheadOfPlayer = SyncedEntry<bool>.op_Implicit(Config.DROP_AHEAD_PLAYER); item.canBeGrabbedBeforeGameStart = SyncedEntry<bool>.op_Implicit(Config.GRABBED_BEFORE_START); item.canBeInspected = false; item.creditsWorth = SyncedEntry<int>.op_Implicit(Config.PRICE); item.floorYOffset = 0; item.restingRotation = new Vector3(0f, 0f, 0f); item.rotationOffset = new Vector3(0f, 0f, 0f); item.positionOffset = new Vector3(0f, 0f, 0f); item.verticalOffset = 0.2f; item.weight = 0.99f + (float)SyncedEntry<int>.op_Implicit(Config.WEIGHT) / 100f; item.minValue = SyncedEntry<int>.op_Implicit(Config.MINIMUM_VALUE); item.maxValue = SyncedEntry<int>.op_Implicit(Config.MAXIMUM_VALUE); item.isScrap = true; item.twoHanded = true; item.itemIcon = val.LoadAsset<Sprite>(text2 + "Icon.png"); item.spawnPrefab = val.LoadAsset<GameObject>(text2 + "ScrapScifiBox.prefab"); item.spawnPrefab.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f); item.dropSFX = val.LoadAsset<AudioClip>(text2 + "Drop.ogg"); item.grabSFX = val.LoadAsset<AudioClip>(text2 + "Grab.ogg"); item.pocketSFX = val.LoadAsset<AudioClip>(text2 + "Pocket.ogg"); item.throwSFX = val.LoadAsset<AudioClip>(text2 + "Throw.ogg"); item.highestSalePercentage = SyncedEntry<int>.op_Implicit(Config.HIGHEST_SALE_PERCENTAGE); item.itemName = "Scrap Sci-fi Box"; item.itemSpawnsOnGround = true; item.isConductiveMetal = SyncedEntry<bool>.op_Implicit(Config.CONDUCTIVE); item.requiresBattery = false; item.batteryUsage = 0f; item.twoHandedAnimation = true; item.grabAnim = "HoldJetpack"; ScifiBoxBehaviour scifiBoxBehaviour2 = item.spawnPrefab.AddComponent<ScifiBoxBehaviour>(); ((GrabbableObject)scifiBoxBehaviour2).itemProperties = item; ((GrabbableObject)scifiBoxBehaviour2).grabbable = true; ((GrabbableObject)scifiBoxBehaviour2).grabbableToEnemies = true; Utilities.FixMixerGroups(item.spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab); switch (Config.SPAWN_MODE.Value) { case ScifiBoxBehaviour.SpawnMode.Store: { TerminalNode val5 = SetupInfoNode(); Items.RegisterShopItem(val2, (TerminalNode)null, (TerminalNode)null, val5, val2.creditsWorth); Items.RegisterItem(item); break; } case ScifiBoxBehaviour.SpawnMode.Scrap: Items.RegisterItem(val2); Items.RegisterScrap(item, SyncedEntry<int>.op_Implicit(Config.RARITY), (LevelTypes)(-1)); break; case ScifiBoxBehaviour.SpawnMode.LimitedScrap: Items.RegisterItem(val2); RegisterLimitedScrap(ref item); break; case ScifiBoxBehaviour.SpawnMode.StoreAndScrap: { TerminalNode val4 = SetupInfoNode(); Items.RegisterShopItem(val2, (TerminalNode)null, (TerminalNode)null, val4, val2.creditsWorth); Items.RegisterScrap(item, SyncedEntry<int>.op_Implicit(Config.RARITY), (LevelTypes)(-1)); break; } case ScifiBoxBehaviour.SpawnMode.StoreAndLimitedScrap: { TerminalNode val3 = SetupInfoNode(); Items.RegisterShopItem(val2, (TerminalNode)null, (TerminalNode)null, val3, val2.creditsWorth); RegisterLimitedScrap(ref item); break; } } InputUtilsCompat.Init(); harmony.PatchAll(typeof(Keybinds)); mls.LogInfo((object)"ScifiBox 1.0.0 has been loaded successfully."); } private void RegisterLimitedScrap(ref Item item) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown Items.RegisterItem(item); AnimationCurve curve = new AnimationCurve((Keyframe[])(object)new Keyframe[3] { new Keyframe(0f, 0f), new Keyframe(1f - Config.SPAWN_CHANCE.Value, 1f), new Keyframe(1f, 1f) }); SpawnableMapObjectDef val = ScriptableObject.CreateInstance<SpawnableMapObjectDef>(); val.spawnableMapObject = new SpawnableMapObject { prefabToSpawn = item.spawnPrefab }; MapObjects.RegisterMapObject(val, (LevelTypes)(-1), (Func<SelectableLevel, AnimationCurve>)((SelectableLevel _) => curve)); } internal static TerminalNode SetupInfoNode() { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); val.displayText = val.displayText + GetDisplayInfo() + "\n"; val.clearPreviousText = true; return val; } public static string GetDisplayInfo() { return $"A portable container which has a maximum capacity of {Config.MAXIMUM_AMOUNT_ITEMS.Value}" + $" and reduces the effective weight of the inserted items by {Config.WEIGHT_REDUCTION_MULTIPLIER.Value * 100f} %.\n" + $"It weighs {Config.WEIGHT.Value} lbs"; } } public static class PluginInfo { public const string PLUGIN_GUID = "ScifiBox"; public const string PLUGIN_NAME = "Wheelbarrow"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace ScifiBox.Util { internal static class Constants { internal const string ITEM_SCAN_NODE_KEY_FORMAT = "Enable scan node of {0}"; internal const bool ITEM_SCAN_NODE_DEFAULT = true; internal const string ITEM_SCAN_NODE_DESCRIPTION = "Shows a scan node on the item when scanning"; internal const string SCIFI_BOX_PRICE_KEY = "Sci-fi Box price"; internal const int SCIFI_BOX_PRICE_DEFAULT = 500; internal const string SCIFI_BOX_PRICE_DESCRIPTION = "Price for Sci-fi Box."; internal const string SCIFI_BOX_WEIGHT_KEY = "Item weight"; internal const int SCIFI_BOX_WEIGHT_DEFAULT = 15; internal const string SCIFI_BOX_WEIGHT_DESCRIPTION = "Weight (in lbs)"; internal const string SCIFI_BOX_CONDUCTIVE_KEY = "Conductive"; internal const bool SCIFI_BOX_CONDUCTIVE_DEFAULT = true; internal const string SCIFI_BOX_CONDUCTIVE_DESCRIPTION = "Wether it attracts lightning to the item or not. (Or other mechanics that rely on item being conductive)"; internal const string SCIFI_BOX_DROP_AHEAD_PLAYER_KEY = "Drop ahead of player when dropping"; internal const bool SCIFI_BOX_DROP_AHEAD_PLAYER_DEFAULT = true; internal const string SCIFI_BOX_DROP_AHEAD_PLAYER_DESCRIPTION = "If on, the item will drop infront of the player. Otherwise, drops underneath them and slightly infront."; internal const string SCIFI_BOX_GRABBED_BEFORE_START_KEY = "Grabbable before game start"; internal const bool SCIFI_BOX_GRABBED_BEFORE_START_DEFAULT = true; internal const string SCIFI_BOX_GRABBED_BEFORE_START_DESCRIPTION = "Allows wether the item can be grabbed before hand or not"; internal const string SCIFI_BOX_HIGHEST_SALE_PERCENTAGE_KEY = "Highest Sale Percentage"; internal const int SCIFI_BOX_HIGHEST_SALE_PERCENTAGE_DEFAULT = 50; internal const string SCIFI_BOX_HIGHEST_SALE_PERCENTAGE_DESCRIPTION = "Maximum percentage of sale allowed when this item is selected for a sale."; internal const string SCIFI_BOX_RESTRICTION_MODE_KEY = "Restrictions on the Sci-fi Box Item"; internal const Restrictions SCIFI_BOX_RESTRICTION_MODE_DEFAULT = 2; internal const string SCIFI_BOX_RESTRICTION_MODE_DESCRIPTION = "Restriction applied when trying to insert an item on the Sci-fi Box.\nSupported values: None, ItemCount, TotalWeight, All"; internal const string SCIFI_BOX_MAXIMUM_WEIGHT_ALLOWED_KEY = "Maximum amount of weight for Sci-fi Box"; internal const float SCIFI_BOX_MAXIMUM_WEIGHT_ALLOWED_DEFAULT = 100f; internal const string SCIFI_BOX_MAXIMUM_WEIGHT_ALLOWED_DESCRIPTION = "How much weight (in lbs and after weight reduction multiplier is applied on the stored items) a Sci-fi Box can carry in items before it is considered full."; internal const string SCIFI_BOX_MAXIMUM_AMOUNT_ITEMS_KEY = "Maximum amount of items for Sci-fi Box"; internal const int SCIFI_BOX_MAXIMUM_AMOUNT_ITEMS_DEFAULT = 4; internal const string SCIFI_BOX_MAXIMUM_AMOUNT_ITEMS_DESCRIPTION = "Amount of items allowed before the Sci-fi Box is considered full"; internal const string SCIFI_BOX_MINIMUM_VALUE_KEY = "Minimum scrap value of Sci-fi Box"; internal const int SCIFI_BOX_MINIMUM_VALUE_DEFAULT = 50; internal const string SCIFI_BOX_MINIMUM_VALUE_DESCRIPTION = "Lower boundary of the scrap's possible value"; internal const string SCIFI_BOX_SPAWN_CHANCE_KEY = "Spawn Chance of the Sci-fi Box Item"; internal const float SCIFI_BOX_SPAWN_CHANCE_DEFAULT = 0.1f; internal const string SCIFI_BOX_SPAWN_CHANCE_DESCRIPTION = "How likely it is for a Sci-fi Box item to spawn when landing on a moon. (0.1 = 10%). Only relevant when LimitedScrap is chosen in the spawn mode"; internal const string SCIFI_BOX_RARITY_KEY = "Scrap Rarity of the Sci-fi Box Item"; internal const int SCIFI_BOX_RARITY_DEFAULT = 10; internal const string SCIFI_BOX_RARITY_DESCRIPTION = "Spawn weight of Sci-fi Box when generating scrap for the level. Only relevant when Scrap is chosen in the spawn mode"; internal const string SCIFI_BOX_MAXIMUM_VALUE_KEY = "Maximum scrap value of Sci-fi Box"; internal const int SCIFI_BOX_MAXIMUM_VALUE_DEFAULT = 100; internal const string SCIFI_BOX_MAXIMUM_VALUE_DESCRIPTION = "Higher boundary of the scrap's possible value"; internal const string SCIFI_BOX_WEIGHT_REDUCTION_MULTIPLIER_KEY = "Weight reduction multiplier for Sci-fi Box"; internal const float SCIFI_BOX_WEIGHT_REDUCTION_MULTIPLIER_DEFAULT = 0.7f; internal const string SCIFI_BOX_WEIGHT_REDUCTION_MUTLIPLIER_DESCRIPTION = "How much an item's weight will be ignored to the Sci-fi Box's total weight"; internal const string SCIFI_BOX_LOOK_SENSITIVITY_DRAWBACK_KEY = "Look sensitivity drawback of the Sci-fi Box Item"; internal const float SCIFI_BOX_LOOK_SENSITIVITY_DRAWBACK_DEFAULT = 0.6f; internal const string SCIFI_BOX_LOOK_SENSITIVITY_DRAWBACK_DESCRIPTION = "Value multiplied on the player's look sensitivity when moving with the Sci-fi Box Item"; internal const string SCIFI_BOX_MOVEMENT_SLOPPY_KEY = "Sloppiness of the Sci-fi Box Item"; internal const float SCIFI_BOX_MOVEMENT_SLOPPY_DEFAULT = 7f; internal const string SCIFI_BOX_MOVEMENT_SLOPPY_DESCRIPTION = "Value multiplied on the player's movement to give the feeling of drifting while carrying the Sci-fi Box Item"; internal const string SCIFI_BOX_SPAWN_MODE_KEY = "Spawn Mode"; internal const ScifiBoxBehaviour.SpawnMode SCIFI_BOX_SPAWN_MODE_DEFAULT = ScifiBoxBehaviour.SpawnMode.LimitedScrap; internal const string SCIFI_BOX_SPAWN_MODE_DESCRIPTION = "Accepted modes: Store (only in the Company Store), Scrap (spawns based on rarity), LimitedScrap (spawns only once based on spawn chance), StoreAndScrap, StoreAndLimitedScrap"; internal const string DROP_ALL_ITEMS_SCIFI_BOX_KEYBIND_NAME = "Drop all items from Sci-fi Box"; internal const string DROP_ALL_ITEMS_SCIFI_BOX_DEFAULT_KEYBIND = "<Mouse>/middleButton"; internal const string DROP_RANDOM_ITEM_SCIFI_BOX_KEYBIND_NAME = "Drop Random Item"; internal const string DROP_RANDOM_ITEM_SCIFI_BOX_DEFAULT_KEYBIND = "<Keyboard>/r"; internal static readonly string SCIFI_BOX_SCAN_NODE_KEY = string.Format("Enable scan node of {0}", "Sci-fi Box"); } } namespace ScifiBox.Misc { [DataContract] public class PluginConfig : SyncedConfig2<PluginConfig> { [field: SyncedEntryField] public SyncedEntry<bool> SCAN_NODE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> PRICE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> WEIGHT { get; set; } [field: SyncedEntryField] public SyncedEntry<bool> DROP_AHEAD_PLAYER { get; set; } [field: SyncedEntryField] public SyncedEntry<bool> GRABBED_BEFORE_START { get; set; } [field: SyncedEntryField] public SyncedEntry<bool> CONDUCTIVE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> HIGHEST_SALE_PERCENTAGE { get; set; } [field: SyncedEntryField] public SyncedEntry<Restrictions> RESTRICTION_MODE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> MAXIMUM_AMOUNT_ITEMS { get; set; } [field: SyncedEntryField] public SyncedEntry<float> MAXIMUM_WEIGHT_ALLOWED { get; set; } [field: SyncedEntryField] public SyncedEntry<float> WEIGHT_REDUCTION_MULTIPLIER { get; set; } [field: SyncedEntryField] public SyncedEntry<float> LOOK_SENSITIVITY_DRAWBACK { get; set; } [field: SyncedEntryField] public SyncedEntry<float> MOVEMENT_SLOPPY { get; set; } [field: SyncedEntryField] public SyncedEntry<ScifiBoxBehaviour.SpawnMode> SPAWN_MODE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> MINIMUM_VALUE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> MAXIMUM_VALUE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> RARITY { get; set; } [field: SyncedEntryField] public SyncedEntry<float> SPAWN_CHANCE { get; set; } public PluginConfig(ConfigFile cfg) : base("com.github.WhiteSpike.ScifiBox") { string text = "Sci-fi Box"; PRICE = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Sci-fi Box price", 500, "Price for Sci-fi Box."); WEIGHT = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Item weight", 15, "Weight (in lbs)"); SCAN_NODE = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, text, Constants.SCIFI_BOX_SCAN_NODE_KEY, true, "Shows a scan node on the item when scanning"); DROP_AHEAD_PLAYER = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, text, "Drop ahead of player when dropping", true, "If on, the item will drop infront of the player. Otherwise, drops underneath them and slightly infront."); CONDUCTIVE = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, text, "Conductive", true, "Wether it attracts lightning to the item or not. (Or other mechanics that rely on item being conductive)"); GRABBED_BEFORE_START = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, text, "Grabbable before game start", true, "Allows wether the item can be grabbed before hand or not"); HIGHEST_SALE_PERCENTAGE = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Highest Sale Percentage", 50, "Maximum percentage of sale allowed when this item is selected for a sale."); RESTRICTION_MODE = SyncedBindingExtensions.BindSyncedEntry<Restrictions>(cfg, text, "Restrictions on the Sci-fi Box Item", (Restrictions)2, "Restriction applied when trying to insert an item on the Sci-fi Box.\nSupported values: None, ItemCount, TotalWeight, All"); MAXIMUM_WEIGHT_ALLOWED = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, text, "Maximum amount of weight for Sci-fi Box", 100f, "How much weight (in lbs and after weight reduction multiplier is applied on the stored items) a Sci-fi Box can carry in items before it is considered full."); MAXIMUM_AMOUNT_ITEMS = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Maximum amount of items for Sci-fi Box", 4, "Amount of items allowed before the Sci-fi Box is considered full"); WEIGHT_REDUCTION_MULTIPLIER = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, text, "Weight reduction multiplier for Sci-fi Box", 0.7f, "How much an item's weight will be ignored to the Sci-fi Box's total weight"); LOOK_SENSITIVITY_DRAWBACK = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, text, "Look sensitivity drawback of the Sci-fi Box Item", 0.6f, "Value multiplied on the player's look sensitivity when moving with the Sci-fi Box Item"); MOVEMENT_SLOPPY = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, text, "Sloppiness of the Sci-fi Box Item", 7f, "Value multiplied on the player's movement to give the feeling of drifting while carrying the Sci-fi Box Item"); SPAWN_MODE = SyncedBindingExtensions.BindSyncedEntry<ScifiBoxBehaviour.SpawnMode>(cfg, text, "Spawn Mode", ScifiBoxBehaviour.SpawnMode.LimitedScrap, "Accepted modes: Store (only in the Company Store), Scrap (spawns based on rarity), LimitedScrap (spawns only once based on spawn chance), StoreAndScrap, StoreAndLimitedScrap"); MINIMUM_VALUE = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Minimum scrap value of Sci-fi Box", 50, "Lower boundary of the scrap's possible value"); MAXIMUM_VALUE = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Maximum scrap value of Sci-fi Box", 100, "Higher boundary of the scrap's possible value"); RARITY = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Scrap Rarity of the Sci-fi Box Item", 10, "Spawn weight of Sci-fi Box when generating scrap for the level. Only relevant when Scrap is chosen in the spawn mode"); SPAWN_CHANCE = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, text, "Spawn Chance of the Sci-fi Box Item", 0.1f, "How likely it is for a Sci-fi Box item to spawn when landing on a moon. (0.1 = 10%). Only relevant when LimitedScrap is chosen in the spawn mode"); ConfigManager.Register<PluginConfig>((SyncedConfig2<PluginConfig>)this); } } internal static class Metadata { public const string GUID = "com.github.WhiteSpike.ScifiBox"; public const string NAME = "ScifiBox"; public const string VERSION = "1.0.0"; } internal static class Tools { internal enum NodeType { GENERAL, DANGER, SCRAP } private static GameObject CreateCanvasScanNode(ref GameObject objectToAddScanNode) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(GameObject.CreatePrimitive((PrimitiveType)3), objectToAddScanNode.transform.position, Quaternion.Euler(Vector3.zero), objectToAddScanNode.transform); ((Object)val).name = "ScanNode"; val.layer = LayerMask.NameToLayer("ScanNode"); Object.Destroy((Object)(object)val.GetComponent<MeshRenderer>()); Object.Destroy((Object)(object)val.GetComponent<MeshFilter>()); return val; } private static void AddScanNode(GameObject objectToAddScanNode, NodeType nodeType, string header = "LGU Scan Node", string subText = "Used for LGU stuff", int creatureScanID = -1, int minRange = 2, int maxRange = 7) { GameObject val = CreateCanvasScanNode(ref objectToAddScanNode); ScanNodeProperties scanNodeProperties = val.AddComponent<ScanNodeProperties>(); ChangeScanNode(ref scanNodeProperties, nodeType, header, subText, creatureScanID, 0, minRange, maxRange); } public static void AddGeneralScanNode(GameObject objectToAddScanNode, string header = "LGU Scan Node", string subText = "Used for LGU stuff", int creatureScanID = -1, int minRange = 2, int maxRange = 7) { AddScanNode(objectToAddScanNode, NodeType.GENERAL, header, subText, creatureScanID, minRange, maxRange); } public static void ChangeScanNode(ref ScanNodeProperties scanNodeProperties, NodeType nodeType, string header = "LGU Scan Node", string subText = "Used for LGU stuff", int creatureScanID = -1, int scrapValue = 0, int minRange = 2, int maxRange = 7) { scanNodeProperties.headerText = header; scanNodeProperties.subText = subText; scanNodeProperties.nodeType = (int)nodeType; scanNodeProperties.creatureScanID = creatureScanID; scanNodeProperties.scrapValue = scrapValue; scanNodeProperties.minRange = minRange; scanNodeProperties.maxRange = maxRange; } } } namespace ScifiBox.Input { internal class IngameKeybinds : LcInputActions { public static IngameKeybinds Instance; [InputAction("<Mouse>/middleButton", Name = "Drop all items from Sci-fi Box")] public InputAction DropAllItemsKey { get; set; } internal static InputActionAsset GetAsset() { return ((LcInputActions)Instance).Asset; } } [HarmonyPatch] internal static class Keybinds { public static InputActionAsset Asset; public static InputActionMap ActionMap; public static InputAction DropAllItemsAction; public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController; [HarmonyPatch(typeof(PreInitSceneScript), "Awake")] [HarmonyPrefix] public static void AddToKeybindMenu() { //IL_0010: 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) Asset = InputUtilsCompat.Asset; ActionMap = Asset.actionMaps[0]; DropAllItemsAction = InputUtilsCompat.DropAllItemsKey; } [HarmonyPatch(typeof(StartOfRound), "OnEnable")] [HarmonyPostfix] public static void OnEnable() { Asset.Enable(); DropAllItemsAction.performed += OnScifiBoxActionPerformed; } [HarmonyPatch(typeof(StartOfRound), "OnDisable")] [HarmonyPostfix] public static void OnDisable() { Asset.Disable(); DropAllItemsAction.performed += OnScifiBoxActionPerformed; } private static void OnScifiBoxActionPerformed(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && localPlayerController.isPlayerControlled && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject) && Object.op_Implicit((Object)(object)localPlayerController.currentlyHeldObjectServer)) { ScifiBoxBehaviour component = ((Component)localPlayerController.currentlyHeldObjectServer).GetComponent<ScifiBoxBehaviour>(); if (Object.op_Implicit((Object)(object)component)) { ((ContainerBehaviour)component).UpdateContainerDrop(); } } } } } namespace ScifiBox.Compat { public static class InputUtilsCompat { internal static InputActionAsset Asset => IngameKeybinds.GetAsset(); public static InputAction DropAllItemsKey => IngameKeybinds.Instance.DropAllItemsKey; internal static void Init() { IngameKeybinds.Instance = new IngameKeybinds(); } } } namespace ScifiBox.Behaviour { public class ScifiBoxBehaviour : ContainerBehaviour { public enum SpawnMode { Store, Scrap, LimitedScrap, StoreAndScrap, StoreAndLimitedScrap } internal const string ITEM_NAME = "Sci-fi Box"; internal const string ITEM_DESCRIPTION = "Allows carrying multiple items"; protected bool KeepScanNode => SyncedEntry<bool>.op_Implicit(Plugin.Config.SCAN_NODE); public string GetDisplayInfo() { return $"A portable container which has a maximum capacity of {Plugin.Config.MAXIMUM_AMOUNT_ITEMS.Value}" + $" and reduces the effective weight of the inserted items by {Plugin.Config.WEIGHT_REDUCTION_MULTIPLIER.Value * 100f} %.\n" + $"It weighs {Plugin.Config.WEIGHT.Value} lbs"; } public override void Start() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) ((ContainerBehaviour)this).Start(); PluginConfig config = Plugin.Config; base.maximumAmountItems = config.MAXIMUM_AMOUNT_ITEMS.Value; base.weightReduceMultiplier = config.WEIGHT_REDUCTION_MULTIPLIER.Value; base.restriction = SyncedEntry<Restrictions>.op_Implicit(config.RESTRICTION_MODE); base.maximumWeightAllowed = config.MAXIMUM_WEIGHT_ALLOWED.Value; base.sloppiness = config.MOVEMENT_SLOPPY.Value; base.lookSensitivityDrawback = config.LOOK_SENSITIVITY_DRAWBACK.Value; base.makeItemsInvisible = true; base.noiseRange = 0f; base.playSounds = false; base.wheelsClip = Array.Empty<AudioClip>(); if (((GrabbableObject)this).itemProperties.isScrap && ((GrabbableObject)this).scrapValue <= 0) { Random random = new Random(StartOfRound.Instance.randomMapSeed + 145); ((GrabbableObject)this).SetScrapValue(random.Next(config.MINIMUM_VALUE.Value, config.MAXIMUM_VALUE.Value)); } } protected override bool ShowDepositPrompts() { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; return localPlayerController.isHoldingObject && (Object)(object)((GrabbableObject)this).playerHeldBy != (Object)(object)localPlayerController; } protected override void SetupScanNodeProperties() { if (!((GrabbableObject)this).itemProperties.isScrap) { ScanNodeProperties scanNodeProperties = ((Component)this).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)scanNodeProperties != (Object)null) { Tools.ChangeScanNode(ref scanNodeProperties, (Tools.NodeType)scanNodeProperties.nodeType, "Sci-fi Box", "Allows carrying multiple items"); } else { Tools.AddGeneralScanNode(((Component)this).gameObject, "Sci-fi Box", "Allows carrying multiple items"); } } } protected override string[] SetupContainerTooltips() { string bindingDisplayString = InputActionRebindingExtensions.GetBindingDisplayString(IngameKeybinds.Instance.DropAllItemsKey, (DisplayStringOptions)0, (string)null); return new string[1] { "Drop all items: [" + bindingDisplayString + "]" }; } protected override void __initializeVariables() { ((ContainerBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "ScifiBoxBehaviour"; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace ScifiBox.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }