using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using BuildInSeatruckPlus.Buildables; using FMODUnity; using HarmonyLib; using Microsoft.CodeAnalysis; using Nautilus.Assets; using Nautilus.Assets.Gadgets; using Nautilus.Assets.PrefabTemplates; using Nautilus.Crafting; using Nautilus.Handlers; using Nautilus.Json; using Nautilus.Options.Attributes; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BuildInSeatruckPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+341eb082facde1de1e99abb1ffd16118b3cf20b6")] [assembly: AssemblyProduct("BuildInSeatruckPlus")] [assembly: AssemblyTitle("BuildInSeatruckPlus")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 BuildInSeatruckPlus { [Menu("Build In Seatruck Plus")] public class Config : ConfigFile { [Keybind("Playback hotkey (in Seatruck / base)")] public KeyCode Hotkey = (KeyCode)114; [Slider("Long-press seconds", 0.1f, 2f, DefaultValue = 0.5f, Step = 0.05f, Format = "{0:F2}")] public float LongPressSeconds = 0.5f; [Toggle("Cheap recipe (1 Titanium) - restart required")] public bool CheapRecipe; [Toggle("Unlock buildables at start - restart required")] public bool UnlockBuildables; [Toggle("New jukeboxes start in shuffle mode")] public bool DefaultShuffle = true; [Toggle("Show 'Now playing' notifications")] public bool ShowTrackName = true; } internal class HotkeyController : MonoBehaviour { private float _downTime = -1f; private bool _longFired; private void Update() { //IL_0032: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) Config config = Plugin.Config; if (config == null || (Object)(object)Player.main == (Object)null) { return; } if (!PlayerInInterior()) { _downTime = -1f; _longFired = false; return; } if (Input.GetKeyDown(config.Hotkey)) { _downTime = Time.unscaledTime; _longFired = false; } if (_downTime >= 0f && !_longFired && Input.GetKey(config.Hotkey) && Time.unscaledTime - _downTime >= config.LongPressSeconds) { _longFired = true; TogglePlayStop(); } if (Input.GetKeyUp(config.Hotkey)) { if (_downTime >= 0f && !_longFired) { NextTrack(); } _downTime = -1f; _longFired = false; } } private static bool PlayerInInterior() { if (!(Player.main.currentInterior is SeaTruckSegment)) { return (Object)(object)Player.main.GetCurrentSub() != (Object)null; } return true; } private static JukeboxInstance ResolveInstance() { IInteriorSpace currentInterior = Player.main.currentInterior; ISpeakerHost host = Speaker.GetHost((MonoBehaviour)(object)((currentInterior is MonoBehaviour) ? currentInterior : null)); if (host == null && (Object)(object)Player.main.GetCurrentSub() != (Object)null) { host = Speaker.GetHost((MonoBehaviour)(object)Player.main.GetCurrentSub()); } foreach (JukeboxInstance item in JukeboxInstance.all) { if (!((Object)(object)item == (Object)null) && Speaker.IsSameHost(Speaker.GetHost((MonoBehaviour)(object)item), host)) { return item; } } return Jukebox.instance; } private void TogglePlayStop() { JukeboxInstance val = ResolveInstance(); if (!((Object)(object)val == (Object)null)) { if (Jukebox.isStartingOrPlaying && (Object)(object)Jukebox.instance == (Object)(object)val) { Jukebox.Stop(); return; } val.shuffle = Plugin.Config.DefaultShuffle; Jukebox.Play(val); } } private void NextTrack() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) JukeboxInstance val = ResolveInstance(); if ((Object)(object)val == (Object)null) { return; } string next = Jukebox.GetNext(val, true); if (string.IsNullOrEmpty(next)) { return; } val.file = next; Jukebox.Play(val); if (Plugin.Config.ShowTrackName) { string label = Jukebox.GetInfo(next).label; if (!string.IsNullOrEmpty(label)) { ErrorMessage.AddMessage("Now playing: " + label); } } } } [BepInPlugin("com.tristyn.buildinseatruckplus", "Build In Seatruck Plus", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "com.tristyn.buildinseatruckplus"; public const string NAME = "Build In Seatruck Plus"; public const string VERSION = "1.0.1"; public static ManualLogSource Log { get; private set; } public static Config Config { get; private set; } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Config = OptionsPanelHandler.RegisterModOptions(); MiniBuildables.Register(); new Harmony("com.tristyn.buildinseatruckplus").PatchAll(); Log.LogInfo((object)"Build In Seatruck Plus 1.0.1 loaded."); ((Component)this).gameObject.AddComponent(); } } internal static class SeaTruckSegmentHelper { public static bool isPlayerInSeaTruckSegment() { if ((Object)(object)Player.main != (Object)null) { return Player.main.currentInterior is SeaTruckSegment; } return false; } public static SeaTruckSegment getCurrentSeaTruckSegment() { if (!((Object)(object)Player.main != (Object)null)) { return null; } IInteriorSpace currentInterior = Player.main.currentInterior; return (SeaTruckSegment)(object)((currentInterior is SeaTruckSegment) ? currentInterior : null); } public static SeaTruckSegment getParentSeaTruckSegment(GameObject gameObject) { return gameObject.GetComponentInParent(); } public static SubRoot getCurrentSeaTruckSegmentSubRoot() { SeaTruckSegment currentSeaTruckSegment = getCurrentSeaTruckSegment(); if (!((Object)(object)currentSeaTruckSegment == (Object)null)) { return ((Component)currentSeaTruckSegment).gameObject.GetComponent(); } return null; } } } namespace BuildInSeatruckPlus.Patches { [HarmonyPatch(typeof(Builder), "CheckAsSubModule")] internal static class Builder_CheckAsSubModule_Patch { private static bool Prefix(out Collider hitCollider, ref bool __result) { //IL_001f: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) hitCollider = null; if ((Object)(object)SeaTruckSegmentHelper.getCurrentSeaTruckSegment() == (Object)null) { return true; } Builder.placementTarget = null; Transform aimTransform = Builder.GetAimTransform(); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(aimTransform.position, aimTransform.forward, ref val, Builder.placeMaxDistance, ((LayerMask)(ref Builder.placeLayerMask)).value, (QueryTriggerInteraction)1)) { __result = false; return false; } if (!Constructable.CheckFlags(Builder.allowedInBase, Builder.allowedInSub, Builder.allowedOutside, Builder.allowedUnderwater, ((RaycastHit)(ref val)).point)) { __result = false; return false; } hitCollider = ((RaycastHit)(ref val)).collider; Builder.placementTarget = ((Component)hitCollider).gameObject; Builder.SetPlaceOnSurface(val, ref Builder.placePosition, ref Builder.placeRotation); __result = true; return false; } } [HarmonyPatch(typeof(Builder), "TryPlace")] internal static class Builder_TryPlace_Patch { private static readonly int UseableLayer = LayerMask.NameToLayer("Useable"); private static bool Prefix(ref bool __result) { //IL_002c: 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_004c: 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_0087: Unknown result type (might be due to invalid IL or missing references) SeaTruckSegment currentSeaTruckSegment = SeaTruckSegmentHelper.getCurrentSeaTruckSegment(); if ((Object)(object)currentSeaTruckSegment == (Object)null) { return true; } if ((Object)(object)Builder.prefab == (Object)null || !Builder.canPlace) { RuntimeManager.PlayOneShot("event:/bz/ui/item_error", default(Vector3)); __result = false; return false; } RuntimeManager.PlayOneShot("event:/tools/builder/place", Builder.ghostModel.transform.position); GameObject obj = Object.Instantiate(Builder.prefab); obj.transform.parent = ((Component)currentSeaTruckSegment).transform; obj.transform.position = Builder.placePosition; obj.transform.rotation = Builder.placeRotation; Constructable componentInParent = obj.GetComponentInParent(); componentInParent.SetState(false, true); if ((Object)(object)Builder.ghostModel != (Object)null) { Object.Destroy((Object)(object)Builder.ghostModel); } componentInParent.SetIsInside(true); SkyEnvironmentChanged.Send(obj, (Component)(object)currentSeaTruckSegment); NeutralizeCollidersForDocking(obj); Builder.ghostModel = null; Builder.prefab = null; Builder.canPlace = false; __result = true; return false; } private static void NeutralizeCollidersForDocking(GameObject go) { Collider[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = UseableLayer; } } } [HarmonyPatch(typeof(Builder), "CheckTag")] internal static class Builder_CheckTag_Patch { private static bool Prefix(Collider c, ref bool __result) { if ((Object)(object)c != (Object)null && (Object)(object)((Component)c).GetComponentInParent() != (Object)null) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Constructable), "CheckFlags")] internal static class Constructable_CheckFlags_Patch { private static bool Prefix(ref bool __result) { if ((Object)(object)SeaTruckSegmentHelper.getCurrentSeaTruckSegment() == (Object)null) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(PowerConsumer), "IsPowered")] internal static class PowerConsumer_IsPowered_Patch { private static bool Prefix(PowerConsumer __instance, ref bool __result) { SeaTruckSegment parentSeaTruckSegment = SeaTruckSegmentHelper.getParentSeaTruckSegment(((Component)__instance).gameObject); if ((Object)(object)parentSeaTruckSegment == (Object)null) { return true; } __result = ((IInteriorSpace)parentSeaTruckSegment).CanBreathe(); return false; } } [HarmonyPatch(typeof(SeaTruckSegment), "CanEnter")] internal static class SeaTruckSegment_CanEnter_Patch { private static bool Prefix(ref bool __result) { __result = true; return false; } } } namespace BuildInSeatruckPlus.Buildables { internal static class MiniBuildables { public static TechType MiniJukebox { get; private set; } public static TechType MiniSpeaker { get; private set; } public static void Register() { //IL_0019: 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) MiniJukebox = Make("MiniJukebox", "Mini Jukebox", "A compact jukebox that fits inside a Seatruck.", (TechType)1564, 0.25f); MiniSpeaker = Make("MiniSpeaker", "Mini Speaker", "A compact speaker for tight interiors.", (TechType)1566, 0.5f); } private static TechType Make(string classId, string friendly, string description, TechType cloneOf, float scale) { //IL_0024: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00b2: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) PrefabInfo val = PrefabInfo.WithTechType(classId, friendly, description, "English", false, (Assembly)null); PrefabInfo val2 = ((PrefabInfo)(ref val)).WithIcon(SpriteManager.Get(cloneOf)); CustomPrefab val3 = new CustomPrefab(val2); CloneTemplate val4 = new CloneTemplate(val2, cloneOf); val4.ModifyPrefab = (Action)Delegate.Combine(val4.ModifyPrefab, (Action)delegate(GameObject go) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Transform transform = go.transform; transform.localScale *= scale; ConstructableBounds[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].bounds.extents = Vector3.one * 0.02f; } Plugin.Log.LogInfo((object)$"{classId}: scaled to {scale} with liberal bounds."); }); val3.SetGameObject((PrefabTemplate)(object)val4); RecipeData val5 = (RecipeData)((!Plugin.Config.CheapRecipe) ? (((object)CraftDataHandler.GetRecipeData(cloneOf)) ?? ((object)new RecipeData((Ingredient[])(object)new Ingredient[1] { new Ingredient((TechType)16, 1) }))) : ((object)new RecipeData((Ingredient[])(object)new Ingredient[1] { new Ingredient((TechType)16, 1) }))); GadgetExtensions.SetRecipe((ICustomPrefab)(object)val3, val5); TechGroup val6 = default(TechGroup); TechCategory val7 = default(TechCategory); int num = default(int); if (CraftData.GetBuilderIndex(cloneOf, ref val6, ref val7, ref num)) { GadgetExtensions.SetPdaGroupCategory((ICustomPrefab)(object)val3, val6, val7); } if (!Plugin.Config.UnlockBuildables) { GadgetExtensions.SetUnlock((ICustomPrefab)(object)val3, (TechType)1564, 1); } val3.Register(); return ((PrefabInfo)(ref val2)).TechType; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }