Decompiled source of Propeller v1.0.0
BepInEx/plugins/Propeller/Propeller.dll
Decompiled 14 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Crest; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Propeller")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Propeller")] [assembly: AssemblyTitle("Propeller")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace JetPump { [BepInPlugin("DogEggz.JetPump", "Propeller", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "DogEggz.JetPump"; internal static ManualLogSource Log; internal static bool Ready; private static ConfigEntry<float> waterOffset; private static ConfigEntry<float> trimAngle; private Harmony harmony; internal static float WaterOffset => Finite(waterOffset, 0f, -0.2f, 0.2f); internal static float TrimAngle => Finite(trimAngle, 80f, 0f, 180f); private static float Finite(ConfigEntry<float> entry, float fallback, float min, float max) { float num = entry?.Value ?? fallback; if (!float.IsNaN(num) && !float.IsInfinity(num)) { return Mathf.Clamp(num, min, max); } return fallback; } internal static void BindSettings(ConfigFile config) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown waterOffset = config.Bind<float>("Water", "Contact offset (metres)", 0f, new ConfigDescription("Small contact calibration only. Positive activates slightly earlier; negative requires deeper immersion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.2f, 0.2f), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); trimAngle = config.Bind<float>("Trim", "Bow-up angle (degrees)", 80f, new ConfigDescription("Average bow-up target during forward propulsion, shared by all propellers on a boat. Zero targets level with pitch compensation, 90 vertical and 180 inverted. Values above 90 permit intentional inversion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); } private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindSettings(((BaseUnityPlugin)this).Config); try { PumpAssets.Load(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); harmony = new Harmony("DogEggz.JetPump"); harmony.PatchAll(typeof(Plugin).Assembly); PumpInput.PatchCheatspeed(harmony); ((Component)this).gameObject.AddComponent<PairingMenu>(); Ready = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Propeller 1.0.0 loaded: Propeller 604 (30,000 N), controller 605, Huge Propeller 606 (600,000 N)."); } catch (Exception ex) { Ready = false; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } PumpAssets.Unload(); ((BaseUnityPlugin)this).Logger.LogError((object)("Propeller initialization aborted: " + ex)); } } private void OnDestroy() { Ready = false; PairingMenu.Close(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } PumpWorld.Reset(); PumpAssets.Unload(); } } internal static class PumpAssets { internal const string BundleName = "dogeggz.jetpump.assets"; internal static AssetBundle Bundle; internal static GameObject Pump; internal static GameObject Controller; internal static GameObject HugePump; internal static void Load(string folder) { string text = Path.Combine(folder, "assets", "dogeggz.jetpump.assets"); Bundle = AssetBundle.LoadFromFile(text); if (!Object.op_Implicit((Object)(object)Bundle)) { throw new FileNotFoundException("Propeller AssetBundle could not be loaded", text); } Pump = Bundle.LoadAsset<GameObject>("Assets/JetPump/Generated/604 propeller.prefab"); Controller = Bundle.LoadAsset<GameObject>("Assets/JetPump/Generated/605 Pump Controller.prefab"); HugePump = Bundle.LoadAsset<GameObject>("Assets/JetPump/Generated/606 Huge Propeller.prefab"); Validate(HugePump, 606); Validate(Pump, 604); Validate(Controller, 605); } private static void Validate(GameObject prefab, int id) { if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab.GetComponent<ShipItem>()) || !Object.op_Implicit((Object)(object)prefab.GetComponent<SaveablePrefab>()) || prefab.GetComponent<SaveablePrefab>().prefabIndex != id || !prefab.GetComponent<ShipItem>().wallAttachment || !Object.op_Implicit((Object)(object)prefab.transform.Find("JetPumpAssetContract_v12"))) { throw new InvalidOperationException("Invalid bundled item " + id); } } internal static bool IsOurItem(ShipItem item) { SaveablePrefab component = ((Component)item).GetComponent<SaveablePrefab>(); if (Object.op_Implicit((Object)(object)component) && PumpState.IsItem(component.prefabIndex)) { return Object.op_Implicit((Object)(object)((Component)item).transform.Find("JetPumpAssetContract_v12")); } return false; } internal static void Register(PrefabsDirectory directory) { GameObject[] array = directory.directory; if (array == null) { throw new InvalidOperationException("Missing prefab directory"); } int[] array2 = new int[3] { 604, 605, 606 }; for (int i = 0; i < array2.Length; i++) { int num = array2[i]; GameObject val = (GameObject)(num switch { 605 => Controller, 604 => Pump, _ => HugePump, }); if (num < array.Length && Object.op_Implicit((Object)(object)array[num]) && (Object)(object)array[num] != (Object)(object)val) { throw new InvalidOperationException("Propeller refuses occupied prefab " + num + " (" + ((Object)array[num]).name + ")."); } } if (array.Length <= 606) { Array.Resize(ref array, 607); } array[604] = Pump; array[605] = Controller; array[606] = HugePump; directory.directory = array; } internal static void Unload() { if (Object.op_Implicit((Object)(object)Bundle)) { Bundle.Unload(false); } Bundle = null; Pump = (Controller = (HugePump = null)); } } [HarmonyPatch(typeof(PrefabsDirectory), "Start")] internal static class RegisterPumpPrefabs { private static void Prefix(PrefabsDirectory __instance) { try { PumpAssets.Register(__instance); } catch (Exception ex) { Plugin.Ready = false; Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(ShipItem), "Awake")] internal static class AddPumpRuntime { private static void Prefix(ShipItem __instance) { if (Plugin.Ready && PumpAssets.IsOurItem(__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PumpItem>())) { ((Component)__instance).gameObject.AddComponent<PumpItem>(); } } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; } internal static class PumpWorld { internal const string SaveKey = "DogEggz.JetPump.v1"; internal static PumpState State = new PumpState(); internal static int Session; internal static bool Loading; internal static readonly List<PumpItem> Live = new List<PumpItem>(); internal static bool SimulationAllowed { get { if (Plugin.Ready && !Loading && State.Writable && GameState.playing && !GameState.currentlyLoading && !GameState.loadingBoatLocalItems && !GameState.justStarted && !GameState.recovering && !Object.op_Implicit((Object)(object)GameState.currentShipyard)) { return Time.timeScale > 0f; } return false; } } internal static bool InputAllowed { get { if (SimulationAllowed && !GameState.sleeping && !Object.op_Implicit((Object)(object)GameState.inBed) && !GameState.inCursorMenu && !GameState.wasInSettingsMenu && !BoatCamera.on) { return !PairingMenu.IsOpen; } return false; } } internal static void Reset() { PairingMenu.Close(); PumpTrim.ResetAll(); PumpMount.ResetCache(); State = new PumpState(); Session++; Loading = false; } internal static void Load() { bool loading = Loading; string value = null; GameState.modData?.TryGetValue("DogEggz.JetPump.v1", out value); State = PumpState.Decode(value); if (loading && State.Writable) { ReconcileSavedNumbers(); } Session++; Loading = false; if (!State.Writable) { Plugin.Log.LogError((object)"JetPump save data is unsupported or invalid. Original data retained; propulsion disabled for this session."); } } internal static void ReconcileSavedNumbers() { SaveLoadManager instance = SaveLoadManager.instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } List<SaveablePrefab> currentPrefabs = instance.GetCurrentPrefabs(); SaveableObject[] array = AccessTools.Field(typeof(SaveLoadManager), "currentObjects").GetValue(instance) as SaveableObject[]; if (currentPrefabs == null || array == null) { return; } HashSet<int> hashSet = new HashSet<int>(); foreach (SaveablePrefab item in currentPrefabs) { if (Object.op_Implicit((Object)(object)item)) { hashSet.Add(item.instanceId); } } SaveableObject[] array2 = array; foreach (SaveableObject val in array2) { if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.localItems)) { continue; } List<SavePrefabData> cachedItems = val.localItems.GetCachedItems(); if (cachedItems == null) { continue; } foreach (SavePrefabData item2 in cachedItems) { hashSet.Add(item2.instanceId); } } State.RetainSavedItems(hashSet); } internal static void Save() { if (!State.Writable || Loading) { return; } foreach (PumpItem item in Live) { if (Object.op_Implicit((Object)(object)item)) { item.EnforceNails(); item.Mount.CapturePose(); } } if (GameState.modData == null) { GameState.modData = new Dictionary<string, string>(); } GameState.modData["DogEggz.JetPump.v1"] = State.Encode(); } internal static PumpItem Find(int id) { for (int i = 0; i < Live.Count; i++) { if (Object.op_Implicit((Object)(object)Live[i]) && !Live[i].Retiring && !Live[i].Mount.Cached && ((Behaviour)Live[i]).isActiveAndEnabled && Object.op_Implicit((Object)(object)Live[i].Saveable) && Live[i].Saveable.instanceId == id) { return Live[i]; } } return null; } internal static void RetireDuplicate(PumpItem incoming, int id) { if (id <= 0) { return; } for (int num = Live.Count - 1; num >= 0; num--) { PumpItem pumpItem = Live[num]; if (Object.op_Implicit((Object)(object)pumpItem) && !((Object)(object)pumpItem == (Object)(object)incoming) && !pumpItem.Retiring && Object.op_Implicit((Object)(object)pumpItem.Saveable) && pumpItem.Saveable.instanceId == id && pumpItem.Saveable.prefabIndex == incoming.Saveable.prefabIndex) { pumpItem.Retiring = true; pumpItem.Item.DestroyItem(); } } } internal static int BoatId(Transform actualBoat) { SaveableObject val = (Object.op_Implicit((Object)(object)actualBoat) ? ((Component)actualBoat).GetComponentInParent<SaveableObject>() : null); if (!Object.op_Implicit((Object)(object)val)) { return 0; } return val.sceneIndex; } internal static bool PairOperational(PumpItem box, out PumpItem pump) { pump = null; if (!Object.op_Implicit((Object)(object)box)) { return false; } box.EnforceNails(); if (!box.CanOperate || !State.ValidPair(box.Record)) { return false; } pump = Find(box.Record.PeerId); if (Object.op_Implicit((Object)(object)pump)) { pump.EnforceNails(); } if (Object.op_Implicit((Object)(object)pump) && pump.Installed && pump.Item.nailed) { return (Object)(object)pump.Item.currentActualBoat == (Object)(object)box.Item.currentActualBoat; } return false; } internal static void AutoPair(PumpItem box) { if (!Object.op_Implicit((Object)(object)box) || !box.CanOperate || box.Record.PeerId != 0 || box.Record.RequirePairChoice) { return; } PumpItem pumpItem = null; foreach (PumpItem item in Live) { if (Object.op_Implicit((Object)(object)item) && item.IsPump && item.Installed && item.Record.PeerId == 0 && !item.Record.RequirePairChoice && !((Object)(object)item.Item.currentActualBoat != (Object)(object)box.Item.currentActualBoat)) { if (Object.op_Implicit((Object)(object)pumpItem)) { return; } pumpItem = item; } } if (Object.op_Implicit((Object)(object)pumpItem)) { State.Pair(box.Record.Id, pumpItem.Record.Id, box.Record.BoatId); } } internal static string WheelKey(GPButtonSteeringWheel wheel, Transform boatRoot) { if (!Object.op_Implicit((Object)(object)wheel) || !Object.op_Implicit((Object)(object)boatRoot) || !((Component)wheel).transform.IsChildOf(boatRoot)) { return ""; } List<string> list = new List<string>(); Transform val = ((Component)wheel).transform; while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)boatRoot) { list.Add(((Object)val).name + "#" + val.GetSiblingIndex()); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } internal static GPButtonSteeringWheel FindWheel(PumpItem box) { Transform val = (Object.op_Implicit((Object)(object)box.Item.currentActualBoat) ? box.Item.currentActualBoat.parent : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } GPButtonSteeringWheel[] componentsInChildren = ((Component)val).GetComponentsInChildren<GPButtonSteeringWheel>(false); GPButtonSteeringWheel val2 = null; GPButtonSteeringWheel[] array = componentsInChildren; foreach (GPButtonSteeringWheel val3 in array) { if (((GoPointerButton)val3).IsStickyClicked() || ((GoPointerButton)val3).IsCliked()) { return val3; } if (!Object.op_Implicit((Object)(object)val2)) { val2 = val3; continue; } return null; } return val2; } internal static PumpItem Selected(GPButtonSteeringWheel wheel) { foreach (PumpItem item in Live) { if (Object.op_Implicit((Object)(object)item) && item.CanOperate && !string.IsNullOrEmpty(item.Record.Wheel) && (Object)(object)item.BoundWheel == (Object)(object)wheel && PairOperational(item, out var _)) { return item; } } return null; } } [HarmonyPatch(typeof(SaveLoadManager), "Awake")] internal static class PumpSessionStart { private static void Prefix() { PumpWorld.Reset(); } } [HarmonyPatch(typeof(SaveLoadManager), "LoadGame")] internal static class PumpBeginLoad { private static void Prefix() { PumpWorld.Reset(); PumpWorld.Loading = true; GameState.modData?.Remove("DogEggz.JetPump.v1"); } } [HarmonyPatch(typeof(SaveLoadManager), "LoadModData")] internal static class PumpLoad { private static void Postfix() { PumpWorld.Load(); } } [HarmonyPatch(typeof(SaveLoadManager), "SaveModData")] internal static class PumpSave { private static void Prefix() { PumpWorld.Save(); } } public sealed class PumpRecord { public int Id; public int Kind; public int PeerId; public int BoatId; public bool Mounted; public int Power = 5; public float Throttle; public bool Enabled; public bool RequireImmersion; public bool RequirePairChoice; public int Number; public string Wheel = ""; public bool HasPose; public float X; public float Y; public float Z; public float Qx; public float Qy; public float Qz; public float Qw = 1f; public float AppliedPower { get { if (!Enabled) { return 0f; } return (float)Power * Throttle; } } public void Normalize() { Power = Math.Max(5, Math.Min(100, (int)Math.Round((double)Power / 5.0) * 5)); Throttle = ((float.IsNaN(Throttle) || float.IsInfinity(Throttle)) ? 0f : Math.Max(0f, Math.Min(1f, Throttle))); if (PeerId < 0) { PeerId = 0; } if (BoatId <= 0) { BoatId = 0; Mounted = false; } Wheel = Wheel ?? ""; if (!Mounted) { Enabled = false; Wheel = ""; } if (!Mounted || !Finite(X) || !Finite(Y) || !Finite(Z) || !Finite(Qx) || !Finite(Qy) || !Finite(Qz) || !Finite(Qw) || Qx * Qx + Qy * Qy + Qz * Qz + Qw * Qw < 0.01f) { HasPose = false; } } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } public void ChangePower(int direction) { Power = Math.Max(5, Math.Min(100, Power + Math.Sign(direction) * 5)); } public void AdjustThrottle(bool forward, bool decrease, float seconds) { if (forward != decrease && !(seconds <= 0f) && !float.IsNaN(seconds) && !float.IsInfinity(seconds)) { Throttle = Math.Max(0f, Math.Min(1f, Throttle + (forward ? 1f : (-1f)) * seconds * 0.2f)); } } public void StopForRemoval() { Enabled = false; Mounted = false; Wheel = ""; HasPose = false; } } public sealed class PumpState { public const int PumpId = 604; public const int ControllerId = 605; public const int HugePumpId = 606; public readonly Dictionary<int, PumpRecord> Items = new Dictionary<int, PumpRecord>(); public bool Writable = true; public bool MigratedNumbers; private static readonly CultureInfo Invariant = CultureInfo.InvariantCulture; public static bool IsPump(int kind) { if (kind != 604) { return kind == 606; } return true; } public static bool IsItem(int kind) { if (!IsPump(kind)) { return kind == 605; } return true; } public static float RatedThrust(int kind) { return kind switch { 604 => 30000f, 606 => 600000f, _ => 0f, }; } public static string Label(PumpRecord pump) { return ((pump.Kind == 606) ? "H.PROP " : "PROP ") + pump.Number.ToString("00"); } public PumpRecord GetOrCreate(int id, int kind) { if (id <= 0 || !IsItem(kind)) { throw new ArgumentException("Invalid item identity."); } if (!Items.TryGetValue(id, out var value)) { Dictionary<int, PumpRecord> items = Items; PumpRecord obj = new PumpRecord { Id = id, Kind = kind }; value = obj; items.Add(id, obj); } if (value.Kind != kind) { throw new InvalidOperationException("Saved item identity belongs to a different prefab."); } return value; } public PumpRecord Peer(PumpRecord item) { if (item != null && Items.TryGetValue(item.PeerId, out var value) && value.PeerId == item.Id && ((item.Kind == 605 && IsPump(value.Kind)) || (value.Kind == 605 && IsPump(item.Kind)))) { return value; } return null; } public bool Pair(int controllerId, int pumpId, int boatId) { if (!Items.TryGetValue(controllerId, out var value) || !Items.TryGetValue(pumpId, out var value2) || value.Kind != 605 || !IsPump(value2.Kind) || boatId <= 0 || !value.Mounted || !value2.Mounted || value.BoatId != boatId || value2.BoatId != boatId) { return false; } if (value2.PeerId != 0 && value2.PeerId != controllerId) { PumpRecord pumpRecord = Peer(value2); if (pumpRecord != null && pumpRecord.Mounted) { return false; } if (pumpRecord != null) { pumpRecord.PeerId = 0; pumpRecord.Wheel = ""; pumpRecord.RequirePairChoice = true; } } PumpRecord pumpRecord2 = Peer(value); if (pumpRecord2 != null && pumpRecord2 != value2) { pumpRecord2.PeerId = 0; pumpRecord2.Enabled = false; } value.PeerId = value2.Id; value2.PeerId = value.Id; value.Wheel = ""; value.RequirePairChoice = false; value2.RequirePairChoice = false; value2.Enabled = false; value2.Throttle = 0f; return true; } public bool ValidPair(PumpRecord box) { PumpRecord pumpRecord = Peer(box); if (box != null && box.Kind == 605 && pumpRecord != null && box.Mounted && pumpRecord.Mounted && box.BoatId > 0) { return pumpRecord.BoatId == box.BoatId; } return false; } public void RemoveFromWall(PumpRecord item) { item.StopForRemoval(); PumpRecord pumpRecord = Peer(item); if (pumpRecord != null) { pumpRecord.Enabled = false; pumpRecord.Wheel = ""; } } public void StopController(PumpRecord box) { if (box != null && box.Kind == 605) { box.Wheel = ""; PumpRecord pumpRecord = Peer(box); if (pumpRecord != null) { pumpRecord.Enabled = false; } } } public void StopPump(PumpRecord pump) { if (pump != null && IsPump(pump.Kind)) { pump.Enabled = false; PumpRecord pumpRecord = Peer(pump); if (pumpRecord != null) { pumpRecord.Wheel = ""; } } } public void Install(PumpRecord item, int boatId) { if (boatId <= 0) { return; } if (item.BoatId != 0 && item.BoatId != boatId) { PumpRecord pumpRecord = Peer(item); if (pumpRecord != null) { pumpRecord.PeerId = 0; pumpRecord.Enabled = false; pumpRecord.Wheel = ""; pumpRecord.RequirePairChoice = true; } item.PeerId = 0; item.RequirePairChoice = true; item.Enabled = false; item.Throttle = 0f; item.Wheel = ""; item.HasPose = false; item.Number = 0; } item.BoatId = boatId; item.Mounted = true; if (IsPump(item.Kind) && item.Number == 0) { item.Number = AvailableNumber(boatId); } } private int AvailableNumber(int boatId) { HashSet<int> hashSet = new HashSet<int>(); foreach (PumpRecord value in Items.Values) { if (IsPump(value.Kind) && value.BoatId == boatId && value.Number > 0) { hashSet.Add(value.Number); } } int i; for (i = 1; hashSet.Contains(i); i++) { } return i; } public void Forget(int id) { if (Items.TryGetValue(id, out var value)) { PumpRecord pumpRecord = Peer(value); if (pumpRecord != null) { pumpRecord.PeerId = 0; pumpRecord.Enabled = false; pumpRecord.Wheel = ""; pumpRecord.RequirePairChoice = true; } Items.Remove(id); } } public void RetainSavedItems(HashSet<int> savedIds) { if (!Writable || savedIds == null) { return; } foreach (int item in new List<int>(Items.Keys)) { if (!savedIds.Contains(item)) { Forget(item); } } if (MigratedNumbers) { RebuildNumbers(); } } private void RebuildNumbers() { List<PumpRecord> list = new List<PumpRecord>(); foreach (PumpRecord value2 in Items.Values) { if (IsPump(value2.Kind)) { list.Add(value2); } } list.Sort((PumpRecord a, PumpRecord b) => (a.Number == b.Number) ? a.Id.CompareTo(b.Id) : a.Number.CompareTo(b.Number)); Dictionary<int, int> dictionary = new Dictionary<int, int>(); foreach (PumpRecord item in list) { if (item.BoatId <= 0) { item.Number = 0; continue; } dictionary.TryGetValue(item.BoatId, out var value); item.Number = value + 1; dictionary[item.BoatId] = item.Number; } } public bool Select(PumpRecord box, string wheel) { if (!ValidPair(box) || string.IsNullOrEmpty(wheel)) { return false; } foreach (PumpRecord value in Items.Values) { if (value.Kind == 605 && value.BoatId == box.BoatId && value.Wheel == wheel) { value.Wheel = ""; } } box.Wheel = wheel; return true; } public string Encode() { StringBuilder stringBuilder = new StringBuilder("JetPump/5\n"); List<int> list = new List<int>(Items.Keys); list.Sort(); foreach (int item in list) { PumpRecord pumpRecord = Items[item]; stringBuilder.Append(pumpRecord.Id).Append('|').Append(pumpRecord.Kind) .Append('|') .Append(pumpRecord.PeerId) .Append('|') .Append(pumpRecord.BoatId) .Append('|') .Append(pumpRecord.Mounted ? 1 : 0) .Append('|') .Append(pumpRecord.Power) .Append('|') .Append(pumpRecord.Throttle.ToString("R", Invariant)) .Append('|') .Append(pumpRecord.Enabled ? 1 : 0) .Append('|') .Append(Convert.ToBase64String(Encoding.UTF8.GetBytes(pumpRecord.Wheel ?? ""))) .Append('|') .Append(pumpRecord.RequirePairChoice ? 1 : 0) .Append('|') .Append(pumpRecord.Number) .Append('|') .Append(pumpRecord.HasPose ? 1 : 0); float[] array = new float[7] { pumpRecord.X, pumpRecord.Y, pumpRecord.Z, pumpRecord.Qx, pumpRecord.Qy, pumpRecord.Qz, pumpRecord.Qw }; foreach (float num in array) { stringBuilder.Append('|').Append(num.ToString("R", Invariant)); } stringBuilder.Append('|').Append(pumpRecord.RequireImmersion ? 1 : 0); stringBuilder.Append('\n'); } return stringBuilder.ToString(); } public static PumpState Decode(string encoded) { PumpState pumpState = new PumpState(); if (string.IsNullOrEmpty(encoded)) { return pumpState; } string[] array = encoded.Split(new char[1] { '\n' }); bool flag = array[0].TrimEnd(new char[1] { '\r' }) == "JetPump/1"; bool flag2 = array[0].TrimEnd(new char[1] { '\r' }) == "JetPump/2"; bool flag3 = array[0].TrimEnd(new char[1] { '\r' }) == "JetPump/3"; bool flag4 = array[0].TrimEnd(new char[1] { '\r' }) == "JetPump/4" || array[0].TrimEnd(new char[1] { '\r' }) == "JetPump/5"; if (!flag && !flag2 && !flag3 && !flag4) { pumpState.Writable = false; return pumpState; } pumpState.MigratedNumbers = flag || flag2; try { for (int i = 1; i < array.Length; i++) { if (string.IsNullOrWhiteSpace(array[i])) { continue; } string[] array2 = array[i].TrimEnd(new char[1] { '\r' }).Split(new char[1] { '|' }); if (array2.Length != (flag ? 11 : (flag4 ? 20 : 19))) { throw new FormatException("Record length"); } PumpRecord pumpRecord = new PumpRecord { Id = int.Parse(array2[0], Invariant), Kind = int.Parse(array2[1], Invariant), PeerId = int.Parse(array2[2], Invariant), BoatId = int.Parse(array2[3], Invariant), Mounted = (array2[4] == "1"), Power = int.Parse(array2[5], Invariant), Throttle = float.Parse(array2[6], Invariant), Enabled = (array2[7] == "1"), Wheel = Encoding.UTF8.GetString(Convert.FromBase64String(array2[8])), RequirePairChoice = (array2[9] == "1"), Number = int.Parse(array2[10], Invariant) }; if (!flag) { pumpRecord.HasPose = array2[11] == "1"; pumpRecord.X = float.Parse(array2[12], Invariant); pumpRecord.Y = float.Parse(array2[13], Invariant); pumpRecord.Z = float.Parse(array2[14], Invariant); pumpRecord.Qx = float.Parse(array2[15], Invariant); pumpRecord.Qy = float.Parse(array2[16], Invariant); pumpRecord.Qz = float.Parse(array2[17], Invariant); pumpRecord.Qw = float.Parse(array2[18], Invariant); } if (flag4) { if (array2[19] != "0" && array2[19] != "1") { throw new FormatException("Immersion switch"); } pumpRecord.RequireImmersion = array2[19] == "1"; } if (pumpRecord.Id <= 0 || !IsItem(pumpRecord.Kind) || pumpState.Items.ContainsKey(pumpRecord.Id)) { throw new FormatException("Record identity"); } pumpRecord.Normalize(); if (IsPump(pumpRecord.Kind) && (pumpRecord.Number < 0 || (pumpRecord.BoatId > 0 && pumpRecord.Number == 0))) { throw new FormatException("Pump label"); } pumpState.Items.Add(pumpRecord.Id, pumpRecord); } if (pumpState.MigratedNumbers) { pumpState.RebuildNumbers(); } HashSet<string> hashSet = new HashSet<string>(); foreach (PumpRecord value2 in pumpState.Items.Values) { if (IsPump(value2.Kind) && value2.BoatId > 0 && !hashSet.Add(value2.BoatId + ":" + value2.Number)) { throw new FormatException("Duplicate boat label"); } } Dictionary<string, PumpRecord> dictionary = new Dictionary<string, PumpRecord>(); foreach (PumpRecord value3 in pumpState.Items.Values) { PumpRecord pumpRecord2 = pumpState.Peer(value3); if (pumpRecord2 == null || !pumpRecord2.Mounted || !value3.Mounted || pumpRecord2.BoatId != value3.BoatId) { value3.Enabled = false; value3.Wheel = ""; } if (value3.Wheel.Length != 0) { string key = value3.BoatId + ":" + value3.Wheel; if (dictionary.TryGetValue(key, out var value)) { value.Wheel = ""; value3.Wheel = ""; } else { dictionary.Add(key, value3); } } } } catch (Exception) { pumpState.Items.Clear(); pumpState.Writable = false; } return pumpState; } } public sealed class PumpItem : MonoBehaviour { internal ShipItem Item; internal SaveablePrefab Saveable; internal PumpRecord Record; internal PumpMount Mount; internal PumpWater Water; internal bool Retiring; private int session = -1; private int warmup; private float reconcileTimer; private Transform rotor; private Transform needle; private Transform lever; private Transform immersionLever; private Vector3 thrustLocal; private Vector3 thrustFacing; private Vector3 rotorAxis; private Vector3 needleAxis; private Quaternion leverBase; private Quaternion immersionBase; private Quaternion needleBase; private TextMesh[] powerDigits; private TextMesh identityText; private PumpPowerDisplay powerDisplay; private readonly PumpDrive drive = new PumpDrive(); private readonly List<PumpControl> controls = new List<PumpControl>(); private Rigidbody boatBody; private PumpTrim trim; private Transform bodyOwner; private string cachedWheelKey; private Transform cachedWheelBoat; private GPButtonSteeringWheel cachedWheel; internal bool IsPump { get { if (Object.op_Implicit((Object)(object)Saveable)) { return PumpState.IsPump(Saveable.prefabIndex); } return false; } } internal bool Installed { get { if (!Retiring && !Mount.Cached && Record != null && Record.Mounted && warmup >= 8 && Item.sold && !Object.op_Implicit((Object)(object)((PickupableItem)Item).held) && Object.op_Implicit((Object)(object)Item.currentActualBoat) && PumpWorld.BoatId(Item.currentActualBoat) == Record.BoatId && Object.op_Implicit((Object)(object)Item.itemRigidbodyC) && Item.itemRigidbodyC.attached && Mount.Verified && (Object)(object)Item.itemRigidbodyC.GetCurrentInventorySlot() == (Object)null && (Object)(object)Item.itemRigidbodyC.GetCurrentBox() == (Object)null && Saveable.currentCrateId == 0) { return ((Component)this).gameObject.layer != 26; } return false; } } internal bool CanOperate { get { if (!IsPump && Installed) { return Item.nailed; } return false; } } internal bool WheelSelected { get { if (CanOperate && Object.op_Implicit((Object)(object)BoundWheel)) { return (Object)(object)PumpWorld.Selected(BoundWheel) == (Object)(object)this; } return false; } } internal GPButtonSteeringWheel BoundWheel { get { if (Record == null || !Object.op_Implicit((Object)(object)Item.currentActualBoat) || string.IsNullOrEmpty(Record.Wheel)) { return null; } if (cachedWheelKey != Record.Wheel || (Object)(object)cachedWheelBoat != (Object)(object)Item.currentActualBoat || !Object.op_Implicit((Object)(object)cachedWheel)) { cachedWheelKey = Record.Wheel; cachedWheelBoat = Item.currentActualBoat; cachedWheel = null; GPButtonSteeringWheel[] componentsInChildren = ((Component)Item.currentActualBoat.parent).GetComponentsInChildren<GPButtonSteeringWheel>(false); foreach (GPButtonSteeringWheel wheel in componentsInChildren) { if (PumpWorld.WheelKey(wheel, Item.currentActualBoat.parent) == Record.Wheel) { cachedWheel = wheel; break; } } } return cachedWheel; } } private void Awake() { //IL_00e6: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_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_0120: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Item = ((Component)this).GetComponent<ShipItem>(); Saveable = ((Component)this).GetComponent<SaveablePrefab>(); Mount = new PumpMount(this); Vector3 val2; if (IsPump) { Transform val = Require("ThrustPoint"); thrustLocal = ((Component)this).transform.InverseTransformPoint(val.position); val2 = ((Component)this).transform.InverseTransformDirection(val.forward); thrustFacing = ((Vector3)(ref val2)).normalized; rotor = Require("RotorPivot"); val2 = rotor.InverseTransformDirection(val.forward); rotorAxis = ((Vector3)(ref val2)).normalized; Water = new PumpWater(this, Require("WaterOpening")); } else { needle = Require("ThrottleNeedlePivot"); lever = Require("OnOffLeverPivot"); needleBase = needle.localRotation; val2 = needle.parent.InverseTransformDirection(((Component)this).transform.forward); needleAxis = ((Vector3)(ref val2)).normalized; leverBase = lever.localRotation; powerDigits = (TextMesh[])(object)new TextMesh[3] { ((Component)Require("PowerTextHundreds")).GetComponent<TextMesh>(), ((Component)Require("PowerTextTens")).GetComponent<TextMesh>(), ((Component)Require("PowerTextOnes")).GetComponent<TextMesh>() }; powerDisplay = new PumpPowerDisplay(((Component)this).transform, powerDigits); AddControl("HIT_OnOff", PumpControl.Action.Toggle, null); AddControl("HIT_PowerDecrease", PumpControl.Action.Decrease, Require("PowerDecreasePivot")); AddControl("HIT_PowerIncrease", PumpControl.Action.Increase, Require("PowerIncreasePivot")); AddControl("HIT_WheelAssign", PumpControl.Action.SelectWheel, Require("WheelAssignPivot")); immersionLever = Require("ImmersionLeverPivot"); immersionBase = immersionLever.localRotation; AddControl("HIT_Immersion", PumpControl.Action.Immersion, null); } identityText = ((Component)Require("IdentityText")).GetComponent<TextMesh>(); } private Transform Require(string name) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return val; } } throw new InvalidOperationException("Propeller asset missing " + name); } private void AddControl(string name, PumpControl.Action action, Transform button) { PumpControl pumpControl = ((Component)Require(name)).gameObject.AddComponent<PumpControl>(); pumpControl.Configure(this, action, button); controls.Add(pumpControl); } private void OnEnable() { if (!PumpWorld.Live.Contains(this)) { PumpWorld.Live.Add(this); } Font.textureRebuilt += RefreshFont; RefreshFont(Object.op_Implicit((Object)(object)identityText) ? identityText.font : null); } private void OnDisable() { StopDrive(resetWater: true); powerDisplay?.Reset(); PumpWorld.Live.Remove(this); Font.textureRebuilt -= RefreshFont; } internal void StopDrive(bool resetWater = false) { drive.Stop(); if (resetWater) { Water?.Reset(); } } private void RefreshFont(Font font) { if (Object.op_Implicit((Object)(object)font) && Object.op_Implicit((Object)(object)identityText) && (Object)(object)identityText.font == (Object)(object)font) { ((Component)identityText).GetComponent<Renderer>().sharedMaterial.mainTexture = font.material.mainTexture; } if (!Object.op_Implicit((Object)(object)font) || powerDigits == null) { return; } TextMesh[] array = powerDigits; foreach (TextMesh val in array) { if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.font == (Object)(object)font) { ((Component)val).GetComponent<Renderer>().sharedMaterial.mainTexture = font.material.mainTexture; } } } internal bool EnsureState() { if (Retiring || PumpWorld.Loading || !PumpWorld.State.Writable || !Object.op_Implicit((Object)(object)Saveable) || Saveable.instanceId <= 0) { return false; } if (session != PumpWorld.Session || Record == null || Record.Id != Saveable.instanceId) { Record = PumpWorld.State.GetOrCreate(Saveable.instanceId, Saveable.prefabIndex); session = PumpWorld.Session; warmup = 0; Mount.ResetBinding(); StopDrive(resetWater: true); powerDisplay?.Reset(); } return true; } internal void Removed() { Mount.Cancel(); StopDrive(resetWater: true); if (EnsureState()) { PumpWorld.State.RemoveFromWall(Record); } } internal void EnforceNails() { if (!Retiring && !Mount.Cached && !PumpWorld.Loading && !GameState.currentlyLoading && Record != null && !Item.nailed) { if (IsPump) { PumpWorld.State.StopPump(Record); } else { PumpWorld.State.StopController(Record); } StopDrive(resetWater: true); } } private void Update() { if (!EnsureState()) { StopDrive(resetWater: true); powerDisplay?.Reset(); SetControls(active: false); return; } EnforceNails(); if (IsPump) { if (Installed && Item.nailed && PumpWorld.SimulationAllowed) { if (Record.RequireImmersion) { Water.Sample(); } else { Water.Reset(); } } else { StopDrive(resetWater: true); } if (!Record.Enabled) { StopDrive(); } } SetControls(CanOperate && PumpWorld.SimulationAllowed); reconcileTimer -= Time.deltaTime; if (reconcileTimer <= 0f && PumpWorld.SimulationAllowed) { reconcileTimer = 0.25f; if (CanOperate) { PumpWorld.AutoPair(this); } if (!Installed && warmup >= 8 && Record.Mounted && (Object.op_Implicit((Object)(object)((PickupableItem)Item).held) || Mount.Stored)) { Removed(); } } RefreshView(); } private void SetControls(bool active) { for (int i = 0; i < controls.Count; i++) { controls[i].SetAvailable(active); } } private void FixedUpdate() { if (!ApplyThrust()) { StopDrive(); } } private bool ApplyThrust() { //IL_01f5: 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_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0237: 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_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) if (!EnsureState() || !Object.op_Implicit((Object)(object)Item.itemRigidbodyC)) { return false; } EnforceNails(); if (!PumpWorld.SimulationAllowed) { return false; } Mount.Tick(); if (Mount.Pending) { return false; } if (warmup < 8) { Item.itemRigidbodyC.attached = Record.Mounted && !Object.op_Implicit((Object)(object)((PickupableItem)Item).held) && Saveable.currentCrateId == 0; warmup++; return false; } if (!IsPump || !Installed || !Item.nailed || Record.AppliedPower <= 0f) { return false; } if (!PumpWorld.PairOperational(PumpWorld.Find(Record.PeerId), out var pump) || (Object)(object)pump != (Object)(object)this) { return false; } if ((Object)(object)bodyOwner != (Object)(object)Item.currentActualBoat || !Object.op_Implicit((Object)(object)boatBody)) { bodyOwner = Item.currentActualBoat; boatBody = (Object.op_Implicit((Object)(object)bodyOwner.parent) ? ((Component)bodyOwner.parent).GetComponent<Rigidbody>() : null); trim = null; } if (!Object.op_Implicit((Object)(object)boatBody) || boatBody.isKinematic || !Object.op_Implicit((Object)(object)Item.currentWalkCol) || (Object)(object)((Component)Item.itemRigidbodyC).transform.parent != (Object)(object)Item.currentWalkCol) { return false; } if (Record.RequireImmersion) { Water.Evaluate(); } float num = Water.Power(Record); if (num <= 0f) { return false; } Vector3 point = ((Component)Item.itemRigidbodyC).transform.TransformPoint(thrustLocal); Vector3 direction = ((Component)Item.itemRigidbodyC).transform.TransformDirection(thrustFacing); Vector3 point2 = ConvertPoint(point, Item.currentWalkCol, Item.currentActualBoat); Vector3 val = ConvertDirection(direction, Item.currentWalkCol, Item.currentActualBoat); if (!Object.op_Implicit((Object)(object)trim)) { trim = ((Component)boatBody).GetComponent<PumpTrim>() ?? ((Component)boatBody).gameObject.AddComponent<PumpTrim>(); } drive.Apply(boatBody, -val, point2, num, Time.fixedDeltaTime, trim, PumpState.RatedThrust(Record.Kind)); return true; } public static Vector3 ConvertPoint(Vector3 point, Transform walk, Transform actual) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return actual.TransformPoint(walk.InverseTransformPoint(point)); } public static Vector3 ConvertDirection(Vector3 direction, Transform walk, Transform actual) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Vector3 val = actual.TransformDirection(walk.InverseTransformDirection(direction)); return ((Vector3)(ref val)).normalized; } private void RefreshView() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_014f: 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) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: 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) PumpRecord pumpRecord = (IsPump ? Record : PumpWorld.State.Peer(Record)); string text = ((pumpRecord == null || pumpRecord.Number <= 0) ? "UNPAIRED" : PumpState.Label(pumpRecord)); if (Object.op_Implicit((Object)(object)identityText) && identityText.text != text) { identityText.text = text; } if (IsPump) { if (Installed && Item.nailed && PumpWorld.SimulationAllowed && Record.Enabled && PumpWorld.PairOperational(PumpWorld.Find(Record.PeerId), out var _)) { rotor.Rotate(rotorAxis, 720f * Record.Throttle * Time.deltaTime, (Space)1); } return; } float num = pumpRecord?.Throttle ?? 0f; needle.localRotation = Quaternion.AngleAxis(Mathf.Lerp(80f, -80f, Mathf.Clamp01(num)), needleAxis) * needleBase; int next = pumpRecord?.Power ?? (-1); powerDisplay.Show(next, Time.deltaTime, !PumpWorld.InputAllowed); lever.localRotation = leverBase * Quaternion.AngleAxis((pumpRecord != null && pumpRecord.Enabled) ? (-50f) : 50f, Vector3.right); immersionLever.localRotation = immersionBase * Quaternion.AngleAxis((pumpRecord != null && pumpRecord.RequireImmersion) ? (-35f) : 35f, Vector3.right); } } public sealed class PumpControl : GoPointerButton { internal enum Action { Toggle, Decrease, Increase, SelectWheel, Immersion } internal PumpItem Owner; private Action action; private Transform button; private Vector3 rest; private Vector3 pressDirection; private Quaternion restRotation; private Vector3 rockerAxis; private GameObject ivory; private Collider hitCollider; private float pressUntil; internal bool CanUse { get { if (Object.op_Implicit((Object)(object)Owner) && Owner.CanOperate) { return PumpWorld.InputAllowed; } return false; } } internal void Configure(PumpItem owner, Action kind, Transform animatedButton) { //IL_0041: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00ba: Unknown result type (might be due to invalid IL or missing references) Owner = owner; action = kind; button = animatedButton; hitCollider = ((Component)this).GetComponent<Collider>(); hitCollider.enabled = false; Vector3 val; if (Object.op_Implicit((Object)(object)button)) { rest = button.localPosition; val = button.parent.InverseTransformDirection(((Component)owner).transform.forward); pressDirection = ((Vector3)(ref val)).normalized * 0.00363f; } if (kind == Action.SelectWheel) { restRotation = button.localRotation; val = button.parent.InverseTransformDirection(((Component)owner).transform.up); rockerAxis = ((Vector3)(ref val)).normalized; Transform[] componentsInChildren = ((Component)button).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == "WheelIvoryStrip") { ivory = ((Component)val2).gameObject; } } if (!Object.op_Implicit((Object)(object)ivory)) { throw new InvalidOperationException("Missing left-edge wheel indicator"); } } base.description = (base.lookText = ""); base.enableRedOutline = false; } internal void SetAvailable(bool available) { if (available) { ((Component)this).gameObject.layer = 0; } if (Object.op_Implicit((Object)(object)hitCollider)) { hitCollider.enabled = available; } base.unclickable = !available; } public override void OnActivate(GoPointer pointer) { if (!Object.op_Implicit((Object)(object)pointer) || !(pointer.GetHeldItem() is ShipItemHammer)) { Activate(); } } public override void OnAltActivate(GoPointer pointer) { if ((!Object.op_Implicit((Object)(object)pointer) || !(pointer.GetHeldItem() is ShipItemHammer)) && CanUse && action == Action.SelectWheel) { PairingMenu.Open(Owner); } } internal void Activate() { if (!CanUse) { return; } PumpRecord pumpRecord = PumpWorld.State.Peer(Owner.Record); if (pumpRecord == null) { if (Owner.Record.PeerId == 0) { PairingMenu.Open(Owner); } else { Notify("Paired propeller is not ready."); } return; } PumpItem pump = PumpWorld.Find(pumpRecord.Id); if (Object.op_Implicit((Object)(object)pump) && !pump.Item.nailed) { Notify("Propeller is not hammered.\nNail it down before use."); return; } if (!PumpWorld.PairOperational(Owner, out pump)) { Notify("Paired propeller is not ready."); return; } switch (action) { case Action.Toggle: pump.Record.Enabled = !pump.Record.Enabled; if (!pump.Record.Enabled) { pump.StopDrive(); } break; case Action.Immersion: pump.Record.RequireImmersion = !pump.Record.RequireImmersion; break; case Action.Decrease: pump.Record.ChangePower(-1); break; case Action.Increase: pump.Record.ChangePower(1); break; case Action.SelectWheel: { GPButtonSteeringWheel val = PumpWorld.FindWheel(Owner); if (Object.op_Implicit((Object)(object)val)) { PumpWorld.State.Select(Owner.Record, PumpWorld.WheelKey(val, Owner.Item.currentActualBoat.parent)); } break; } } pressUntil = Time.time + 0.14f; } private static void Notify(string message) { if (Object.op_Implicit((Object)(object)NotificationUi.instance)) { NotificationUi.instance.ShowNotification(message); } } public override void ExtraLateUpdate() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)button)) { bool flag = ((action != Action.SelectWheel) ? (Time.time < pressUntil) : (Object.op_Implicit((Object)(object)Owner) && Owner.WheelSelected)); if (action == Action.SelectWheel) { button.localRotation = Quaternion.AngleAxis(flag ? (-10f) : 10f, rockerAxis) * restRotation; ivory.SetActive(flag); } else { button.localPosition = rest + (flag ? pressDirection : Vector3.zero); } } } } internal sealed class PumpMount { private static readonly MethodInfo EnterBoat = AccessTools.Method(typeof(ShipItem), "EnterBoat", (Type[])null, (Type[])null); private static readonly MethodInfo Targeter = AccessTools.Method(typeof(ShipItem), "SetUpTargeter", (Type[])null, (Type[])null); private static readonly FieldInfo ItemSave = AccessTools.Field(typeof(ShipItem), "saveable"); private static readonly FieldInfo TargeterActive = AccessTools.Field(typeof(GoPointerTargeter), "targeterActive"); private static BoatEmbarkCollider[] boats; private static float nextBoatScan; private static readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[64]; private readonly PumpItem owner; private readonly BoxCollider housing; private Collider contact; private Vector3 contactPosition; private Quaternion contactRotation; private bool previewValid; private bool recoveryChecked; private BoatEmbarkCollider bound; internal bool Pending; internal bool LoadedFromSave; internal bool Stored { get { if (owner.Saveable.currentCrateId == 0 && ((Component)owner).gameObject.layer != 26) { if (Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC)) { if (!Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC.GetCurrentBox())) { return Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC.GetCurrentInventorySlot()); } return true; } return false; } return true; } } internal bool Cached { get { if (Object.op_Implicit((Object)(object)owner.Saveable)) { if (owner.Saveable.GetParentObject() != -2) { return owner.Saveable.GetParentObject() == -3; } return true; } return false; } } internal bool ProtectOwnership { get { if (!Cached) { if (!Object.op_Implicit((Object)(object)((PickupableItem)owner.Item).held) && !Stored) { if (!Pending) { if (owner.Record != null) { return owner.Record.Mounted; } return false; } return true; } return false; } return true; } } internal bool Verified { get { if (Object.op_Implicit((Object)(object)bound) && (Object)(object)owner.Item.currentActualBoat == (Object)(object)((Component)bound).transform.parent && (Object)(object)owner.Item.currentWalkCol == (Object)(object)bound.walkCollider && (Object)(object)((Component)owner.Item).transform.parent == (Object)(object)((Component)bound).transform.parent && Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC) && (Object)(object)((Component)owner.Item.itemRigidbodyC).transform.parent == (Object)(object)bound.walkCollider) { return owner.Saveable.GetParentObject() == PumpWorld.BoatId(((Component)bound).transform.parent); } return false; } } internal PumpMount(PumpItem owner) { this.owner = owner; housing = ((Component)owner).GetComponent<BoxCollider>(); } internal static void ResetCache() { boats = null; nextBoatScan = 0f; } internal void ResetBinding() { bound = null; recoveryChecked = false; } internal void Cancel() { Pending = (previewValid = false); contact = null; bound = null; LoadedFromSave = false; } private static BoatEmbarkCollider[] Boats() { if (boats == null || Time.unscaledTime >= nextBoatScan) { boats = Object.FindObjectsOfType<BoatEmbarkCollider>(); nextBoatScan = Time.unscaledTime + 2f; } return boats; } private static bool Usable(BoatEmbarkCollider boat) { if (!Object.op_Implicit((Object)(object)boat) || !Object.op_Implicit((Object)(object)boat.walkCollider) || !Object.op_Implicit((Object)(object)((Component)boat).transform.parent) || !Object.op_Implicit((Object)(object)((Component)boat).transform.parent.parent) || !Object.op_Implicit((Object)(object)((Component)boat).GetComponent<Collider>())) { return false; } Transform parent = ((Component)boat).transform.parent.parent; if (Object.op_Implicit((Object)(object)((Component)parent).GetComponent<Rigidbody>()) && Object.op_Implicit((Object)(object)((Component)parent).GetComponent<BoatMass>())) { return PumpWorld.BoatId(((Component)boat).transform.parent) > 0; } return false; } internal static BoatEmbarkCollider ResolveSurface(Collider surface, out Transform frame) { frame = null; if (!Object.op_Implicit((Object)(object)surface) || Object.op_Implicit((Object)(object)((Component)surface).GetComponentInParent<ShipItem>()) || Object.op_Implicit((Object)(object)((Component)surface).GetComponentInParent<ItemRigidbody>())) { return null; } BoatEmbarkCollider val = null; BoatEmbarkCollider[] array = Boats(); foreach (BoatEmbarkCollider val2 in array) { if (!Usable(val2)) { continue; } Transform val3 = (((Component)surface).transform.IsChildOf(val2.walkCollider) ? val2.walkCollider : (((Component)surface).transform.IsChildOf(((Component)val2).transform.parent.parent) ? ((Component)val2).transform.parent : null)); if (Object.op_Implicit((Object)(object)val3)) { if (Object.op_Implicit((Object)(object)val) && (Object)(object)((Component)val).transform.parent != (Object)(object)((Component)val2).transform.parent) { frame = null; return null; } val = val2; frame = val3; } } return val; } private static BoatEmbarkCollider FindSavedBoat(int id) { if (id <= 0) { return null; } BoatEmbarkCollider[] array = Boats(); foreach (BoatEmbarkCollider val in array) { if (Usable(val) && PumpWorld.BoatId(((Component)val).transform.parent) == id) { return val; } } return null; } private bool Raycast(Ray ray, float distance, out RaycastHit hit) { //IL_0000: 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_0039: 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_00da: Unknown result type (might be due to invalid IL or missing references) int num = Physics.RaycastNonAlloc(ray, hits, distance, -5, (QueryTriggerInteraction)1); RaycastHit[] array = ((num == hits.Length) ? Physics.RaycastAll(ray, distance, -5, (QueryTriggerInteraction)1) : hits); if (array != hits) { num = array.Length; } hit = default(RaycastHit); float num2 = float.PositiveInfinity; for (int i = 0; i < num; i++) { Collider collider = ((RaycastHit)(ref array[i])).collider; if (Object.op_Implicit((Object)(object)collider) && !((Component)collider).transform.IsChildOf(((Component)owner).transform) && (!Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC) || !((Component)collider).transform.IsChildOf(((Component)owner.Item.itemRigidbodyC).transform)) && ((RaycastHit)(ref array[i])).distance < num2) { num2 = ((RaycastHit)(ref array[i])).distance; hit = array[i]; } } return Object.op_Implicit((Object)(object)((RaycastHit)(ref hit)).collider); } internal static Quaternion SurfaceRotation(Vector3 normal, Vector3 itemUp) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane((normal.y > 0.8f) ? itemUp : Vector3.up, normal); if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.ProjectOnPlane(itemUp, normal); } if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.ProjectOnPlane(Vector3.forward, normal); } return Quaternion.LookRotation(-normal, ((Vector3)(ref val)).normalized); } internal bool Preview(Transform proxy, out Vector3 position, out Quaternion rotation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) previewValid = false; position = Vector3.zero; rotation = Quaternion.identity; if (!Object.op_Implicit((Object)(object)proxy) || !Object.op_Implicit((Object)(object)((PickupableItem)owner.Item).held) || !PumpWorld.InputAllowed) { return false; } if (!Raycast(new Ray(proxy.position, proxy.forward), 1.3f, out var hit) || ((RaycastHit)(ref hit)).distance < 0.1f) { return false; } if (!Object.op_Implicit((Object)(object)ResolveSurface(((RaycastHit)(ref hit)).collider, out var _))) { return false; } rotation = SurfaceRotation(((RaycastHit)(ref hit)).normal, ((Component)owner).transform.up); position = ClearancePosition(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, rotation); RememberContact(((RaycastHit)(ref hit)).collider, position, rotation); return true; } internal Vector3 ClearancePosition(Vector3 point, Vector3 normal, Quaternion rotation) { //IL_0086: 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_008f: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if (Object.op_Implicit((Object)(object)housing)) { Vector3 val = housing.size * 0.5f; for (int i = -1; i <= 1; i += 2) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { num = Mathf.Min(num, Vector3.Dot(rotation * (housing.center + Vector3.Scale(val, new Vector3((float)i, (float)j, (float)k))), normal)); } } } } return point + normal * (0.001f - num); } internal void RememberContact(Collider surface, Vector3 position, Quaternion rotation) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) contact = surface; contactPosition = ((Component)surface).transform.InverseTransformPoint(position); contactRotation = Quaternion.Inverse(((Component)surface).transform.rotation) * rotation; previewValid = true; } internal void Drop(bool attached) { Pending = attached && previewValid && Object.op_Implicit((Object)(object)contact); bound = null; } internal void Tick() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0111: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) if (Cached || owner.Retiring || Object.op_Implicit((Object)(object)((PickupableItem)owner.Item).held) || Stored || !owner.Item.sold || !Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC) || !Object.op_Implicit((Object)(object)owner.Item.itemRigidbodyC.GetBody()) || ItemSave.GetValue(owner.Item) == null) { return; } if (Pending) { if (!Object.op_Implicit((Object)(object)contact)) { Pending = false; return; } Transform frame; BoatEmbarkCollider val = ResolveSurface(contact, out frame); if (Object.op_Implicit((Object)(object)val)) { Vector3 local = frame.InverseTransformPoint(((Component)contact).transform.TransformPoint(contactPosition)); Quaternion localRot = Quaternion.Inverse(frame.rotation) * ((Component)contact).transform.rotation * contactRotation; if (Bind(val, local, localRot)) { PumpWorld.State.Install(owner.Record, PumpWorld.BoatId(((Component)val).transform.parent)); CapturePose(); Pending = false; } } } else if (owner.Record.Mounted && !Verified) { int parentObject = owner.Saveable.GetParentObject(); if (parentObject > 0 && parentObject != owner.Record.BoatId) { return; } BoatEmbarkCollider val2 = FindSavedBoat(owner.Record.BoatId); PumpRecord record = owner.Record; if (Object.op_Implicit((Object)(object)val2)) { ? local2 = (record.HasPose ? new Vector3(record.X, record.Y, record.Z) : ((Component)val2).transform.parent.InverseTransformPoint(((Component)owner).transform.position)); Quaternion localRot2; if (!record.HasPose) { localRot2 = Quaternion.Inverse(((Component)val2).transform.parent.rotation) * ((Component)owner).transform.rotation; } else { Quaternion val3 = new Quaternion(record.Qx, record.Qy, record.Qz, record.Qw); localRot2 = ((Quaternion)(ref val3)).normalized; } if (Bind(val2, (Vector3)local2, localRot2)) { CapturePose(); } } } else { if (owner.Record.Mounted || !LoadedFromSave || recoveryChecked) { return; } recoveryChecked = true; Vector3 forward = ((Component)owner).transform.forward; if (Raycast(new Ray(((Component)owner).transform.position - forward * 0.05f, forward), 0.07f, out var hit) && !(Vector3.Distance(((RaycastHit)(ref hit)).point, ((Component)owner).transform.position) > 0.012f) && !(Vector3.Dot(-((RaycastHit)(ref hit)).normal, forward) < 0.985f)) { Transform frame2; BoatEmbarkCollider val4 = ResolveSurface(((RaycastHit)(ref hit)).collider, out frame2); if (Object.op_Implicit((Object)(object)val4) && (owner.Saveable.GetParentObject() <= 0 || owner.Saveable.GetParentObject() == PumpWorld.BoatId(((Component)val4).transform.parent)) && !((Object)(object)frame2 != (Object)(object)((Component)val4).transform.parent) && Bind(val4, frame2.InverseTransformPoint(((Component)owner).transform.position), Quaternion.Inverse(frame2.rotation) * ((Component)owner).transform.rotation)) { PumpWorld.State.Install(owner.Record, PumpWorld.BoatId(((Component)val4).transform.parent)); CapturePose(); } } } } internal void CapturePose() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00f7: Unknown result type (might be due to invalid IL or missing references) if (!Cached && !owner.Retiring && Verified && owner.Record != null && owner.Record.Mounted && !Object.op_Implicit((Object)(object)((PickupableItem)owner.Item).held) && !Stored) { Transform currentActualBoat = owner.Item.currentActualBoat; Vector3 val = currentActualBoat.InverseTransformPoint(((Component)owner).transform.position); Quaternion val2 = Quaternion.Inverse(currentActualBoat.rotation) * ((Component)owner).transform.rotation; PumpRecord record = owner.Record; record.X = val.x; record.Y = val.y; record.Z = val.z; record.Qx = val2.x; record.Qy = val2.y; record.Qz = val2.z; record.Qw = val2.w; record.HasPose = true; } } private bool Bind(BoatEmbarkCollider boat, Vector3 local, Quaternion localRot) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) ShipItem item = owner.Item; ItemRigidbody itemRigidbodyC = item.itemRigidbodyC; if (!Usable(boat) || !Object.op_Implicit((Object)(object)itemRigidbodyC) || !Object.op_Implicit((Object)(object)itemRigidbodyC.GetBody()) || ItemSave.GetValue(item) == null) { return false; } if (Object.op_Implicit((Object)(object)item.currentActualBoat) && (Object)(object)item.currentActualBoat != (Object)(object)((Component)boat).transform.parent) { itemRigidbodyC.ExitBoat(); } ((Component)item).transform.position = ((Component)boat).transform.parent.TransformPoint(local); ((Component)item).transform.rotation = ((Component)boat).transform.parent.rotation * localRot; EnterBoat.Invoke(item, new object[1] { ((Component)boat).GetComponent<Collider>() }); itemRigidbodyC.attached = true; itemRigidbodyC.GetBody().velocity = Vector3.zero; itemRigidbodyC.GetBody().angularVelocity = Vector3.zero; itemRigidbodyC.GetBody().isKinematic = true; bound = boat; return Verified; } internal void ShowPreview(Vector3 position, Quaternion rotation) { //IL_0018: 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) Targeter.Invoke(owner.Item, new object[3] { position, rotation, ((Component)owner).GetComponent<MeshFilter>().sharedMesh }); } internal void HidePreview() { GoPointerTargeter targeter = ((PickupableItem)owner.Item).held.GetTargeter(); if (Object.op_Implicit((Object)(object)targeter)) { TargeterActive.SetValue(targeter, false); } } } [HarmonyPatch(typeof(ShipItem), "Update")] internal static class PumpPlacementPreview { [HarmonyPriority(0)] private static void Postfix(ShipItem __instance, Transform ___itemRigidbody, ref bool ___inRangeOfWall, ref Vector3 ___attachPos, ref Quaternion ___attachRot) { //IL_0039: 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) PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)((PickupableItem)__instance).held)) { ___inRangeOfWall = component.Mount.Preview(___itemRigidbody, out ___attachPos, out ___attachRot); if (___inRangeOfWall) { component.Mount.ShowPreview(___attachPos, ___attachRot); } else { component.Mount.HidePreview(); } } } } [HarmonyPatch(typeof(ShipItem), "ExtraFixedUpdate")] internal static class PumpKeepMountedBoat { private static bool Prefix(ShipItem __instance) { PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component)) { return !component.Mount.ProtectOwnership; } return true; } } [HarmonyPatch(typeof(SaveablePrefab), "Load")] internal static class PumpLoadedPlacement { private static void Prefix(SaveablePrefab __instance, SavePrefabData data, bool ___loaded) { PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component) && !___loaded) { PumpWorld.RetireDuplicate(component, data.instanceId); } } private static void Postfix(SaveablePrefab __instance) { PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component)) { component.Mount.LoadedFromSave = true; component.Mount.ResetBinding(); PumpMount.ResetCache(); } } } [HarmonyPatch(typeof(SaveablePrefab), "PrepareSaveData")] internal static class PumpSavePose { private static void Prefix(SaveablePrefab __instance) { ((Component)__instance).GetComponent<PumpItem>()?.Mount.CapturePose(); } } [HarmonyPatch(typeof(GoPointer), "MainButtonDown")] internal static class PumpClickWhileSteering { private static int activatedFrame = -1; private static void Postfix(GoPointer __instance, GoPointerButton ___stickyClickedButton, GoPointerButton ___pointedAtButton, ref bool __result) { if (!__result || __instance.GetHeldItem() is ShipItemHammer) { return; } GPButtonSteeringWheel val = (GPButtonSteeringWheel)(object)((___stickyClickedButton is GPButtonSteeringWheel) ? ___stickyClickedButton : null); if (val == null) { return; } PumpControl pumpControl = ___pointedAtButton as PumpControl; if (Object.op_Implicit((Object)(object)pumpControl) && pumpControl.CanUse && ((Component)val).transform.IsChildOf(pumpControl.Owner.Item.currentActualBoat.parent)) { if (activatedFrame != Time.frameCount) { activatedFrame = Time.frameCount; pumpControl.Activate(); } __result = false; } } } [HarmonyPatch(typeof(GoPointer), "GetPointedAtItem")] internal static class PumpHammerTarget { private static void Postfix(GoPointer __instance, GoPointerButton ___pointedAtButton, ref ShipItem __result) { if (__instance.GetHeldItem() is ShipItemHammer && ___pointedAtButton is PumpControl pumpControl && Object.op_Implicit((Object)(object)pumpControl.Owner)) { __result = pumpControl.Owner.Item; } } } [HarmonyPatch(typeof(ShipItemHammer), "AllowOnItemClick")] internal static class PumpHammerAllowed { private static bool Prefix(GoPointerButton lookedAtButton, ref bool __result) { if (!(lookedAtButton is PumpControl pumpControl) || !Object.op_Implicit((Object)(object)pumpControl.Owner)) { return true; } __result = ShipItemHammer.CanNail(pumpControl.Owner.Item); return false; } } [HarmonyPatch(typeof(ShipItemHammer), "NailItem")] internal static class PumpHammerMovingMount { private static bool Prefix(ShipItem item) { PumpItem pumpItem = (Object.op_Implicit((Object)(object)item) ? ((Component)item).GetComponent<PumpItem>() : null); if (!Object.op_Implicit((Object)(object)pumpItem)) { return true; } if (PumpWorld.InputAllowed && pumpItem.Installed) { item.nailed = true; if (Object.op_Implicit((Object)(object)UISoundPlayer.instance)) { UISoundPlayer.instance.PlayUISound((UISounds)11, 1f, 0.6f); } } return false; } } [HarmonyPatch(typeof(ShipItem), "OnPickup")] internal static class PumpPickup { private static void Prefix(ShipItem __instance) { ((Component)__instance).GetComponent<PumpItem>()?.Removed(); } } [HarmonyPatch(typeof(ShipItem), "OnDrop")] internal static class PumpDrop { private static void Postfix(ShipItem __instance, bool ___inRangeOfWall) { PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component)) { component.Mount.Drop(__instance.sold && ___inRangeOfWall && !((GoPointerButton)__instance).forceDisableRedOutline && Object.op_Implicit((Object)(object)__instance.itemRigidbodyC) && __instance.itemRigidbodyC.attached); } } } [HarmonyPatch(typeof(ShipItem), "OnEnterInventory")] internal static class PumpInventory { private static void Prefix(ShipItem __instance) { ((Component)__instance).GetComponent<PumpItem>()?.Removed(); } } [HarmonyPatch(typeof(ShipItem), "DestroyItem")] internal static class PumpDestroy { private static void Prefix(ShipItem __instance) { PumpItem component = ((Component)__instance).GetComponent<PumpItem>(); if (Object.op_Implicit((Object)(object)component)) { if (!component.Retiring && !component.Mount.Cached && !PumpWorld.Loading && !GameState.currentlyLoading && component.EnsureState()) { component.Removed(); PumpWorld.State.Forget(component.Saveable.instanceId); } component.Retiring = true; } } } internal sealed class PumpPowerDisplay { private static readonly string[] Labels = new string[11] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-" }; private readonly TextMesh[] digits; private readonly Transform[] pivots = (Transform[])(object)new Transform[3]; private readonly Quaternion[] restRotation = (Quaternion[])(object)new Quaternion[3]; private readonly Vector3[] restPosition = (Vector3[])(object)new Vector3[3]; private readonly Vector3[] axis = (Vector3[])(object)new Vector3[3]; private readonly Vector3[] outward = (Vector3[])(object)new Vector3[3]; private readonly int[] shown = new int[3]; private readonly int[] target = new int[3]; private readonly float[] elapsed = new float[3] { 0.25f, 0.25f, 0.25f }; private readonly float[] direction = new float[3]; private int value = int.MinValue; internal PumpPowerDisplay(Transform panel, TextMesh[] texts) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) digits = texts; for (int i = 0; i < 3; i++) { pivots[i] = ((Component)texts[i]).transform.parent.parent; restRotation[i] = pivots[i].localRotation; restPosition[i] = pivots[i].localPosition; Vector3[] array = axis; int num = i; Vector3 val = pivots[i].parent.InverseTransformDirection(panel.right); array[num] = ((Vector3)(ref val)).normalized; Vector3[] array2 = outward; int num2 = i; val = pivots[i].parent.InverseTransformDirection(-panel.forward); array2[num2] = ((Vector3)(ref val)).normalized; } } internal void Reset() { value = int.MinValue; } internal void Show(int next, float dt, bool immediate) { //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) bool flag = immediate || value == int.MinValue || next < 0 || value < 0; if (next != value || flag) { int num = 100; int num2 = 0; while (num2 < 3) { int num3 = ((next < 0) ? 10 : (next / num % 10)); if (flag) { shown[num2] = (target[num2] = num3); elapsed[num2] = 0.25f; digits[num2].text = Labels[num3]; } else if (target[num2] != num3) { target[num2] = num3; if (elapsed[num2] >= 0.25f) { elapsed[num2] = 0f; direction[num2] = ((next > value) ? 1f : (-1f)); } } num2++; num /= 10; } value = next; } for (int i = 0; i < 3; i++) { float num4 = elapsed[i]; elapsed[i] = Mathf.Min(0.25f, elapsed[i] + Mathf.Max(0f, dt)); if (num4 < 0.125f && elapsed[i] >= 0.125f) { shown[i] = target[i]; digits[i].text = Labels[shown[i]]; } if (elapsed[i] >= 0.25f && shown[i] != target[i]) { elapsed[i] = 0f; } float num5 = elapsed[i] / 0.25f; float num6 = direction[i] * ((num5 < 0.5f) ? (180f * num5) : (-180f * (1f - num5))); pivots[i].localRotation = Quaternion.AngleAxis(num6, axis[i]) * restRotation[i]; pivots[i].localPosition = restPosition[i] + outward[i] * (0.016f * Mathf.Sin(Mathf.Abs(num6) * (MathF.PI / 180f))); } } } public sealed class PairingMenu : MonoBehaviour { private static PumpItem owner; private static bool open; private static bool previousCursor; private static bool previousMouse; private static bool previousControl; private static bool previousVisible; private static CursorLockMode previousLock; private Vector2 scroll; internal static bool IsOpen => open; internal static void Open(PumpItem box) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)box) && box.CanOperate && !IsOpen && !GameState.inCursorMenu) { owner = box; open = true; previousCursor = GameState.inCursorMenu; previousMouse = MouseLook.MouseLookIsEnabled(); previousControl = Object.op_Implicit((Object)(object)Refs.charController) && ((Collider)Refs.charController).enabled; previousVisible = Cursor.visible; previousLock = Cursor.lockState; GameState.inCursorMenu = true; MouseLook.ToggleMouseLook(false); Refs.SetPlayerControl(false); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } internal static void Close() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (open) { open = false; owner = null; GameState.inCursorMenu = previousCursor; MouseLook.ToggleMouseLook(previousMouse); if (Object.op_Implicit((Object)(object)Refs.charController)) { Refs.SetPlayerControl(previousControl); } Cursor.lockState = previousLock; Cursor.visible = previousVisible; } } private void OnDisable() { Close(); } private void Update() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (open) { if (!Object.op_Implicit((Object)(object)owner)) { Close(); } else if (!owner.CanOperate || !GameState.playing || GameState.currentlyLoading || GameState.recovering || !Object.op_Implicit((Object)(object)Camera.main) || Vector3.Distance(((Component)Camera.main).transform.position, ((Component)owner).transform.position) > 3f || Input.GetKeyDown((KeyCode)27)) { Close(); } } } private void OnGUI() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner) && !owner.CanOperate) { Close(); } else { if (!Object.op_Implicit((Object)(object)owner)) { return; } float num = Mathf.Min(500f, (float)Screen.width - 30f); float num2 = Mathf.Min(380f, (float)Screen.height - 30f); GUILayout.BeginArea(new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2), GUI.skin.box); GUILayout.Label("PAIR THIS CONTROLLER", Array.Empty<GUILayoutOption>()); scroll = GUILayout.BeginScrollView(scroll, Array.Empty<GUILayoutOption>()); int num3 = 0; foreach (PumpItem item in PumpWorld.Live) { if (!Object.op_Implicit((Object)(object)item) || !item.IsPump || !item.Installed || (Object)(object)item.Item.currentActualBoat != (Object)(object)owner.Item.currentActualBoat) { continue; } PumpRecord pumpRecord = PumpWorld.State.Peer(item.Record); if (pumpRecord != null && pumpRecord.Id != owner.Record.Id && pumpRecord.Mounted) { continue; } num3++; Vector3 val = owner.Item.currentActualBoat.InverseTransformPoint(((Component)item).transform.position); string text = ((val.x < -0.1f) ? "port" : ((val.x > 0.1f) ? "starboard" : "centre")); if (GUILayout.Button(PumpState.Label(item.Record) + " - " + text + " (fore/aft " + val.z.ToString("F1") + " m)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(38f) })) { if (PumpWorld.State.Peer(owner.Record) == item.Record || PumpWorld.State.Pair(owner.Record.Id, item.Record.Id, owner.Record.BoatId)) { Close(); } else if (Object.op_Implicit((Object)(object)NotificationUi.instance)) { NotificationUi.instance.ShowNotification("Propeller is not available for pairing."); } break; } } if (num3 == 0) { GUILayout.Label("No available propeller.", Array.Empty<GUILayoutOption>()); } GUILayout.EndScrollView(); if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) })) { Close(); } GUILayout.EndArea(); } } } [HarmonyPatch(typeof(GoPointer), "PositionItemInBuyUI")] internal static class PropellerCarry { private static bool Prefix(GoPointer __instance, PickupableItem item) { //IL_0038: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00be: Unknown result type (might be due to invalid IL or missing references) SaveablePrefab val = (Object.op_Implicit((Object)(object)item) ? ((Component)item).GetComponent<SaveablePrefab>() : null); if (!Plugin.Ready || !Object.op_Implicit((Object)(object)val) || val.prefabIndex != 606) { return true; } Transform transform = ((Component)__instance).transform; Vector3 val2 = transform.position + transform.forward * item.holdDistance + transform.up * item.holdHeight; ((Component)item).transform.position = Vector3.Lerp(((Component)item).transform.position, val2, Time.deltaTime * 9f); if (Object.op_Implicit((Object)(object)BuyItemUI.instance) && Object.op_Implicit((Object)(object)BuyItemUI.instance.itemPos)) { ((Component)item).transform.rotation = BuyItemUI.instance.itemPos.rotation; } return false; } } [HarmonyPatch(typeof(ShopItemSpawner), "Start")] internal static class AcademyStock { internal const string SceneName = "island 8 A Academy"; internal const string ExtraName = "JetPump Academy controller left"; internal const string ThirdName = "Propeller Academy controller far left"; internal const string HugeName = "Propeller Academy huge"; [HarmonyPrefix] [HarmonyPriority(0)] private static void Prefix(ShopItemSpawner __instance) { //IL_000d: 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_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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might