Decompiled source of New Beginnings v1.5.9
BepInEx/plugins/NewBeginnings/NewBeginnings.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.5.9.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyVersion("1.5.9.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 NewBeginnings { internal sealed class EquipmentEntry { internal readonly string Key; internal readonly string DisplayName; internal readonly int Index; internal readonly string PrefabName; internal readonly string ItemType; internal readonly bool IsModded; internal readonly bool AllowScaledPacking; internal readonly string SourceName = ""; internal readonly string SourceId = ""; internal EquipmentEntry(int index, string prefabName, string itemType, string displayName, string key = null) { Index = index; PrefabName = prefabName; ItemType = itemType; DisplayName = displayName; Key = key ?? ("native:" + index + ":" + prefabName); } internal EquipmentEntry(int index, string prefabName, string itemType, string displayName, string sourceId, string sourceName, bool allowScaledPacking = false) : this(index, prefabName, itemType, displayName) { IsModded = true; AllowScaledPacking = allowScaledPacking; SourceId = sourceId; SourceName = sourceName; Key = "mod:" + Uri.EscapeDataString(sourceId) + ":" + Uri.EscapeDataString(ModEquipment.CanonicalName(prefabName)) + ":" + Uri.EscapeDataString(itemType); } } internal static class AdditionalEquipment { internal const string WallHooksKey = "bundle:wallhooks"; private const int WallHooksPerBox = 12; private const float HookRowOffset = -4.5f; private static readonly EquipmentEntry[] Definitions = new EquipmentEntry[59] { new EquipmentEntry(1, "1 crate salmon (E)", "ShipItemCrate", "Box of salmon"), new EquipmentEntry(10, "10 barrel water", "ShipItemBottle", "Barrel of water"), new EquipmentEntry(11, "11 barrel rum", "ShipItemBottle", "Barrel of rum"), new EquipmentEntry(52, "52 cheese", "ShipItemFood", "Single cheese"), new EquipmentEntry(40, "40 empty bottle", "ShipItemBottle", "Empty bottle"), new EquipmentEntry(70, "70 bucket", "ShipItemBottle", "Bucket"), new EquipmentEntry(108, "108 crate of firewood", "ShipItemCrate", "Crate of firewood"), new EquipmentEntry(80, "80 compass A", "ShipItemCompass", "Compass (Al'Ankh)"), new EquipmentEntry(81, "81 compass E", "ShipItemCompass", "Compass (Emerald)"), new EquipmentEntry(82, "82 compass M", "ShipItemCompass", "Compass (Aestrin)"), new EquipmentEntry(83, "83 chronometer A", "ShipItemCompass", "Chronocompass (Al'Ankh)"), new EquipmentEntry(84, "84 chronometer E", "ShipItemCompass", "Chronocompass (Emerald)"), new EquipmentEntry(85, "85 chronometer M", "ShipItemCompass", "Chronocompass (Aestrin)"), new EquipmentEntry(86, "86 sun compass A", "ShipItemCompass", "Sun compass"), new EquipmentEntry(90, "90 quadrant", "ShipItemQuadrant", "Quadrant"), new EquipmentEntry(92, "92 chip log M", "ShipItemChipLog", "Chip log (Aestrin)"), new EquipmentEntry(93, "93 chip log E", "ShipItemChipLog", "Chip log (Emerald)"), new EquipmentEntry(94, "94 broom", "ShipItemBroom", "Broom"), new EquipmentEntry(95, "95 fishing rod 1", "ShipItemFishingRod", "Fishing rod"), new EquipmentEntry(104, "104 crate of fishing hooks", "ShipItemCrate", "Box of fishing hooks"), new EquipmentEntry(104, "104 crate of fishing hooks", "ShipItemCrate", "Box of wall hooks", "bundle:wallhooks"), new EquipmentEntry(100, "100 mug wood", "ShipItemBottle", "Mug (wood)"), new EquipmentEntry(101, "101 mug clay", "ShipItemBottle", "Mug (clay)"), new EquipmentEntry(102, "102 mug metal", "ShipItemBottle", "Mug (metal)"), new EquipmentEntry(103, "103 mug metal gold", "ShipItemBottle", "Mug (gold)"), new EquipmentEntry(110, "110 lantern A", "ShipItemLight", "Lantern (Al'Ankh)"), new EquipmentEntry(111, "111 lantern E yellow", "ShipItemLight", "Lantern (yellow)"), new EquipmentEntry(112, "112 lantern E red", "ShipItemLight", "Lantern (red)"), new EquipmentEntry(113, "113 lantern E green", "ShipItemLight", "Lantern (green)"), new EquipmentEntry(114, "114 lantern M", "ShipItemLight", "Lantern (Aestrin)"), new EquipmentEntry(115, "115 map ocean", "ShipItemFoldable", "Ocean map"), new EquipmentEntry(116, "116 map A", "ShipItemFoldable", "Al'Ankh map"), new EquipmentEntry(117, "117 map E", "ShipItemFoldable", "Emerald Archipelago map"), new EquipmentEntry(118, "118 map M", "ShipItemFoldable", "Aestrin map"), new EquipmentEntry(119, "119 map L", "ShipItemFoldable", "Fire Fish Lagoon map"), new EquipmentEntry(131, "131 lantern candle crate", "ShipItemCrate", "Box of candles"), new EquipmentEntry(132, "132 lantern oil bottle", "ShipItemLanternFuel", "Lamp oil"), new EquipmentEntry(133, "133 lantern M big", "ShipItemLight", "Lantern (large Aestrin)"), new EquipmentEntry(134, "134 lantern E blu", "ShipItemLight", "Lantern (blue)"), new EquipmentEntry(156, "156 pot", "ShipItemSoup", "Cooking pot"), new EquipmentEntry(157, "157 pot big", "ShipItemSoup", "Large cooking pot"), new EquipmentEntry(159, "159 hammer", "ShipItemHammer", "Hammer"), new EquipmentEntry(160, "160 spyglass big", "ShipItemSpyglass", "Spyglass (large)"), new EquipmentEntry(161, "161 spyglass small", "ShipItemSpyglass", "Spyglass (small)"), new EquipmentEntry(162, "162 spyglass tiny", "ShipItemSpyglass", "Spyglass (tiny)"), new EquipmentEntry(165, "165 map mirage mountain", "ShipItemFoldable", "Mirage Mountain map"), new EquipmentEntry(166, "166 oakum", "ShipItemOakum", "Oakum"), new EquipmentEntry(167, "167 ink set", "ShipItemInkSet", "Charting kit"), new EquipmentEntry(168, "168 oar", "ShipItemOar", "Oar"), new EquipmentEntry(170, "170 clock A", "ShipItemClock", "Chronometer (Al'Ankh)"), new EquipmentEntry(171, "171 clock E", "ShipItemClock", "Chronometer (Emerald)"), new EquipmentEntry(172, "172 clock M", "ShipItemClock", "Chronometer (Aestrin)"), new EquipmentEntry(213, "213 (43) crate oranges", "ShipItemCrate", "Box of oranges"), new EquipmentEntry(370, "370 slicing knife A", "ShipItemKnife", "Knife (Al'Ankh)"), new EquipmentEntry(371, "371 slicing knife E", "ShipItemKnife", "Knife (Emerald)"), new EquipmentEntry(372, "372 slicing knife M", "ShipItemKnife", "Knife (Aestrin)"), new EquipmentEntry(382, "382 kettle A", "ShipItemKettle", "Kettle (Al'Ankh)"), new EquipmentEntry(383, "383 kettle E", "ShipItemKettle", "Kettle (Emerald)"), new EquipmentEntry(384, "384 kettle M", "ShipItemKettle", "Kettle (Aestrin)") }; private static readonly HashSet<ShipItem> Extras = new HashSet<ShipItem>(); private static readonly HashSet<ShipItem> PackingCandidates = new HashSet<ShipItem>(); private static readonly HashSet<ShipItem> ScaledPackingTools = new HashSet<ShipItem>(); private static readonly HashSet<ShipItem> ScaledStarterMaps = new HashSet<ShipItem>(); private static readonly List<ShipItem> Carriers = new List<ShipItem>(); private static readonly Dictionary<ShipItem, ShipItem> Packed = new Dictionary<ShipItem, ShipItem>(); private static readonly Dictionary<ShipItem, ShipItem> WallHooks = new Dictionary<ShipItem, ShipItem>(); private static readonly HashSet<ShipItem> WallHookBoxes = new HashSet<ShipItem>(); private static readonly HashSet<ShipItem> Purchased = new HashSet<ShipItem>(); private static ResolvedStart owner; private static bool appended; private static bool appendSucceeded; private static bool packingComplete; private static string failure; private static Object crateUi; private static readonly Type CrateType = typeof(ShipItem).Assembly.GetType("CrateInventory"); private static readonly Type CrateUiType = typeof(ShipItem).Assembly.GetType("CrateInventoryUI"); private static readonly MethodInfo Insert = ((CrateType == null) ? null : AccessTools.Method(CrateType, "InsertItem", new Type[1] { typeof(ShipItem) }, (Type[])null)); private static readonly FieldInfo Contents = ((CrateType == null) ? null : AccessTools.Field(CrateType, "containedItems")); private static readonly FieldInfo CrateId = AccessTools.Field(typeof(SaveablePrefab), "currentCrateId"); private static readonly FieldInfo UiMeshes = ((CrateUiType == null) ? null : AccessTools.Field(CrateUiType, "containerMeshes")); private static readonly FieldInfo UiButtons = ((CrateUiType == null) ? null : AccessTools.Field(CrateUiType, "buttons")); private static readonly FieldInfo BodyBoxes = AccessTools.Field(typeof(ItemRigidbody), "subcolliders"); private static PrefabsDirectory Directory => PrefabsDirectory.instance ?? Resources.FindObjectsOfTypeAll<PrefabsDirectory>().FirstOrDefault(); internal static EquipmentEntry[] GetCatalog() { PrefabsDirectory directory = Directory; return Definitions.Where((EquipmentEntry entry) => (Object)(object)Resolve(directory, entry) != (Object)null).OrderBy<EquipmentEntry, string>((EquipmentEntry entry) => entry.DisplayName, StringComparer.OrdinalIgnoreCase).Concat(ModEquipment.Discover(directory)) .ToArray(); } private static GameObject Resolve(PrefabsDirectory directory, EquipmentEntry entry) { if (directory?.directory == null || entry.Index >= directory.directory.Length) { return null; } GameObject val = directory.directory[entry.Index]; if ((Object)(object)val == (Object)null || ((Object)val).name != entry.PrefabName) { return null; } ShipItem component = val.GetComponent<ShipItem>(); SaveablePrefab component2 = val.GetComponent<SaveablePrefab>(); if (entry.Key == "bundle:wallhooks" && !CanCreateWallHookBox(directory, val)) { return null; } if (!((Object)(object)component != (Object)null) || !(((object)component).GetType().FullName == entry.ItemType) || !((Object)(object)component2 != (Object)null) || component2.prefabIndex != entry.Index) { return null; } return val; } private static GameObject WallHookPrefab(PrefabsDirectory directory) { return Resolve(directory, new EquipmentEntry(79, "79 lamp hanger generic", "ShipItemLampHook", "")); } private static bool CanCreateWallHookBox(PrefabsDirectory directory, GameObject crate) { GameObject val = WallHookPrefab(directory); if ((Object)(object)val != (Object)null && CanPack(val.GetComponent<ShipItem>())) { return CarrierCapacity(crate) >= 12; } return false; } private static void AppendWallHookBox(Transform staging, Vector3 origin, List<GameObject> created) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) PrefabsDirectory directory = Directory; ShipItem val = Clone(Resolve(directory, new EquipmentEntry(104, "104 crate of fishing hooks", "ShipItemCrate", "")), staging, origin, created.Count); created.Add(((Component)val).gameObject); val.amount = 0f; Extras.Add(val); WallHookBoxes.Add(val); GameObject prefab = WallHookPrefab(directory); Vector3 origin2 = origin + new Vector3(0f, 0f, -4.5f); for (int i = 0; i < 12; i++) { ShipItem val2 = Clone(prefab, staging, origin2, WallHooks.Count); created.Add(((Component)val2).gameObject); Extras.Add(val2); WallHooks.Add(val2, val); } } internal static bool TryValidateSelection(IEnumerable<string> selected, out string reason) { reason = null; HashSet<string> hashSet = new HashSet<string>(selected ?? Array.Empty<string>(), StringComparer.Ordinal); NormalizeSelection(hashSet); if (hashSet.Count == 0) { return true; } PrefabsDirectory directory = Directory; EquipmentEntry[] catalog = GetCatalog(); foreach (string key in hashSet) { EquipmentEntry equipmentEntry = catalog.FirstOrDefault((EquipmentEntry candidate) => candidate.Key == key); if (equipmentEntry == null || (Object)(object)Resolve(directory, equipmentEntry) == (Object)null) { reason = "Additional equipment is unavailable in this game version: " + (equipmentEntry?.DisplayName ?? key) + ". Clear that selection before starting."; return false; } } return true; } internal static void NormalizeSelection(HashSet<string> selected) { selected.Remove("native:139:139 map F"); selected.Remove("native:381:381 brining jar small"); if (selected.Remove("native:71:71 fuel wood")) { selected.Add("native:108:108 crate of firewood"); } if (selected.Remove("native:99:99 fishing hook")) { selected.Add("native:104:104 crate of fishing hooks"); } if (selected.Remove("native:130:130 lantern candle")) { selected.Add("native:131:131 lantern candle crate"); } } internal static void Reset() { owner = null; appended = false; appendSucceeded = false; packingComplete = false; failure = null; crateUi = null; Extras.Clear(); PackingCandidates.Clear(); ScaledPackingTools.Clear(); ScaledStarterMaps.Clear(); Carriers.Clear(); Packed.Clear(); WallHooks.Clear(); WallHookBoxes.Clear(); Purchased.Clear(); } private static void CompletePurchase(ShipItem item) { if ((Object)(object)item == (Object)null || !(item is ShipItemFishingRod) || !Extras.Contains(item) || !item.sold || !Purchased.Add(item)) { return; } try { item.OnBuy(); } catch (Exception exception) { Plugin.Instance?.Error("Could not finish setting up a starter fishing rod. It may not be able to cast.", exception); } } internal static void CompleteLoosePurchases() { if (GameState.currentlyLoading) { return; } ShipItem[] array = Extras.ToArray(); foreach (ShipItem val in array) { if (!Packed.ContainsKey(val)) { CompletePurchase(val); } } } internal static bool IsExtra(ShipItem item) { if (item != null) { return Extras.Contains(item); } return false; } internal static bool IsCarrier(ShipItem item) { if (item != null) { if (!Carriers.Contains(item)) { return WallHookBoxes.Contains(item); } return true; } return false; } internal static bool IsAdditional(ShipItem item) { if (!IsExtra(item)) { return IsCarrier(item); } return true; } internal static bool IsPacked(ShipItem item) { if (item != null) { return Packed.ContainsKey(item); } return false; } internal static bool Append(ResolvedStart selected, IEnumerable<ShipItem> nativeCandidates) { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) if (appended) { return appendSucceeded; } owner = selected; appended = true; PackingCandidates.UnionWith(nativeCandidates.Where((ShipItem item) => (Object)(object)item != (Object)null)); ScaledStarterMaps.UnionWith(PackingCandidates.Where(IsNativeStarterMap)); StartingOptionsSettings options = selected.Options?.Copy() ?? new StartingOptionsSettings(); options.NormalizeEquipment(); if (!options.TryValidate(out var reason) || !TryValidateSelection(options.EquipmentQuantities.Keys, out reason)) { Plugin.Instance?.Warn(reason + " The normal starter supplies will still be placed."); packingComplete = true; return false; } PrefabsDirectory directory = Directory; EquipmentEntry[] array = (from entry in GetCatalog() where options.EquipmentQuantities.ContainsKey(entry.Key) select entry).ToArray(); List<GameObject> list = new List<GameObject>(); GameObject val = null; try { val = new GameObject("NewBeginnings equipment staging"); val.SetActive(false); Vector3 position = ((Component)selected.StarterSet).transform.position; ShipItem val2 = ((Component)selected.StarterSet).GetComponentsInChildren<ShipItem>(true).FirstOrDefault(); if ((Object)(object)val2 != (Object)null) { position = ((Component)val2).transform.position; } EquipmentEntry[] array2 = array; foreach (EquipmentEntry equipmentEntry in array2) { for (int num2 = 0; num2 < options.EquipmentQuantities[equipmentEntry.Key]; num2++) { if (equipmentEntry.Key == "bundle:wallhooks") { AppendWallHookBox(val.transform, position, list); continue; } ShipItem val3 = Clone(Resolve(directory, equipmentEntry), val.transform, position, list.Count); list.Add(((Component)val3).gameObject); Extras.Add(val3); if (equipmentEntry.AllowScaledPacking) { ScaledPackingTools.Add(val3); } PackingCandidates.Add(val3); } } GameObject prefab = Resolve(directory, new EquipmentEntry(104, "104 crate of fishing hooks", "ShipItemCrate", "")); int num3 = CarrierCapacity(prefab); PackingCandidates.IntersectWith(PackingCandidates.Where(CanPack).ToArray()); if (num3 > 0) { int count = PackingCandidates.Count; for (int num4 = 0; num4 < ((long)count + (long)num3 - 1) / num3; num4++) { ShipItem val4 = Clone(prefab, val.transform, position, list.Count); list.Add(((Component)val4).gameObject); val4.amount = 0f; Carriers.Add(val4); } } else if (PackingCandidates.Count > 0) { Plugin.Instance?.Warn("Native starter crates are unavailable; starter supplies will use dockside ground placement."); } foreach (GameObject item in list) { item.transform.SetParent(((Component)selected.StarterSet).transform, true); } appendSucceeded = true; return true; } catch (Exception exception) { foreach (GameObject item2 in list) { item2.SetActive(false); item2.transform.SetParent(((Object)(object)val == (Object)null) ? null : val.transform, true); Object.Destroy((Object)(object)item2); } Reset(); owner = selected; appended = true; packingComplete = true; Plugin.Instance?.Error("Starter crate and additional equipment initialization failed; normal supplies will use dockside ground placement.", exception); return false; } finally { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } private static ShipItem Clone(GameObject prefab, Transform staging, Vector3 origin, int ordinal) { //IL_0026: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(prefab, staging, false); obj.SetActive(false); Good component = obj.GetComponent<Good>(); if (component != null) { component.RegisterAsMissionless(); } obj.transform.SetPositionAndRotation(origin + new Vector3((float)(ordinal % 8) * 0.5f, 2f + (float)(ordinal / 8) * 0.5f, 1.5f), Quaternion.identity); return obj.GetComponent<ShipItem>(); } private static int CarrierCapacity(GameObject prefab) { if ((Object)(object)prefab == (Object)null || Insert == null || Contents == null || CrateId == null || UiMeshes == null || UiButtons == null || BodyBoxes == null) { return 0; } if (crateUi == (Object)null) { crateUi = Resources.FindObjectsOfTypeAll(CrateUiType).FirstOrDefault(); } if (crateUi == (Object)null) { return 0; } Mesh[] array = UiMeshes.GetValue(crateUi) as Mesh[]; Array array2 = UiButtons.GetValue(crateUi) as Array; MeshFilter component = prefab.GetComponent<MeshFilter>(); Mesh val = ((component != null) ? component.sharedMesh : null); if (array == null || array2 == null || (Object)(object)val == (Object)null) { return 0; } return Math.Min(Array.IndexOf(array, val) switch { 3 => 8, 2 => 30, 1 => 20, 0 => 12, _ => 0, }, array2.Length); } private static bool IsNativeStarterMap(ShipItem item) { if ((Object)(object)item == (Object)null || ((object)item).GetType() != typeof(ShipItemFoldable)) { return false; } SaveablePrefab component = ((Component)item).GetComponent<SaveablePrefab>(); if ((Object)(object)component == (Object)null) { return false; } return component.prefabIndex switch { 116 => ((Object)((Component)item).gameObject).name == "116 map A", 117 => ((Object)((Component)item).gameObject).name == "117 map E", 118 => ((Object)((Component)item).gameObject).name == "118 map M", _ => false, }; } private static bool CanPack(ShipItem item) { return CanPack(item, ScaledPackingTools.Contains(item) || ScaledStarterMaps.Contains(item)); } internal static bool CanPack(ShipItem item, bool allowScaledPacking) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0026: 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) if ((Object)(object)item != (Object)null && !((PickupableItem)item).big) { Vector3 val = ((Component)item).transform.localScale - Vector3.one; if (!(((Vector3)(ref val)).sqrMagnitude < 1E-06f)) { if (allowScaledPacking) { return ModEquipment.ValidScale(((Component)item).transform.localScale); } return false; } return true; } return false; } internal static bool TryPack(ResolvedStart selected, Action<ShipItem> prepare, out string reason) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) reason = failure; if (failure != null) { return false; } if (owner != selected || packingComplete) { return true; } try { foreach (KeyValuePair<ShipItem, ShipItem> wallHook in WallHooks) { if (!Packed.ContainsKey(wallHook.Key)) { ShipItem key = wallHook.Key; ShipItem value = wallHook.Value; if ((Object)(object)((PickupableItem)key).held != (Object)null || (Object)(object)((PickupableItem)value).held != (Object)null) { reason = "a wall-hook box was picked up before packing"; return false; } Component component = ((Component)value).GetComponent(CrateType); if (!key.sold || !value.sold || ((Component)value).GetComponent<SaveablePrefab>().instanceId <= 0 || (Object)(object)component == (Object)null) { reason = "waiting for native wall-hook box ownership"; return false; } if (((IList)Contents.GetValue(component)).Count >= CarrierCapacity(((Component)value).gameObject)) { throw new InvalidOperationException("wall-hook box has no free native inventory slot"); } prepare(key); ((Component)key).transform.SetPositionAndRotation(((Component)value).transform.position, ((Component)value).transform.rotation); PrepareLikeHeld(key); Insert.Invoke(component, new object[1] { key }); Packed.Add(key, value); } } if (Carriers.Count == 0) { packingComplete = true; return true; } foreach (ShipItem item in PackingCandidates.Where(CanPack)) { if (!Packed.ContainsKey(item)) { if ((Object)(object)((PickupableItem)item).held != (Object)null) { reason = "a starter item was picked up before packing"; return false; } ShipItem val = ((IEnumerable<ShipItem>)Carriers).FirstOrDefault((Func<ShipItem, bool>)((ShipItem candidate) => (Object)(object)candidate != (Object)null && (Object)(object)((PickupableItem)candidate).held == (Object)null && (Object)(object)((Component)candidate).GetComponent(CrateType) != (Object)null && ((IList)Contents.GetValue(((Component)candidate).GetComponent(CrateType))).Count < CarrierCapacity(((Component)candidate).gameObject))); if ((Object)(object)val == (Object)null) { reason = "waiting for an available native equipment crate"; return false; } if (!item.sold || !val.sold || ((Component)val).GetComponent<SaveablePrefab>().instanceId <= 0) { reason = "waiting for native starter-item ownership"; return false; } CompletePurchase(item); prepare(item); ((Component)item).transform.SetPositionAndRotation(((Component)val).transform.position, ((Component)val).transform.rotation); PrepareLikeHeld(item); Insert.Invoke(((Component)val).GetComponent(CrateType), new object[1] { item }); Packed.Add(item, val); } } packingComplete = true; return true; } catch (Exception ex) { failure = (reason = "native equipment packing failed: " + ex.Message); return false; } } private static void PrepareLikeHeld(ShipItem item) { item.ResetRigidbody(); if (!(BodyBoxes.GetValue(item.GetItemRigidbody()) is List<Collider> list)) { return; } foreach (Collider item2 in list) { if ((Object)(object)item2 != (Object)null) { item2.isTrigger = true; } } } internal static void MovePacked(Action<ShipItem> resetDistance) { //IL_002d: 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) foreach (KeyValuePair<ShipItem, ShipItem> item in Packed) { ((Component)item.Key).transform.SetPositionAndRotation(((Component)item.Value).transform.position, ((Component)item.Value).transform.rotation); item.Key.ResetRigidbody(); item.Key.GetItemRigidbody().ForceRigidbodyToWalkCol(); resetDistance(item.Key); } } } internal static class BerthClearance { internal struct Footprint { internal Vector2 A; internal Vector2 B; internal float Radius; } internal struct HullDimensions { internal Vector3 Center; internal float Radius; internal float Length; internal float HalfSegment; } private const float Margin = 1f; private const float MaximumSide = 12f; private const float MaximumRear = 4f; internal static Vector3 AdjustCrabBeach(ResolvedStart selected, Vector3 nativePosition) { //IL_0021: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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_017c: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_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_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: 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) if (!KnownSites.IsCrabBeach(selected.Port)) { return nativePosition; } Transform boatPos = selected.Recovery.boatPos; Footprint own = ReadHull(selected.Body, nativePosition, boatPos.rotation); List<Footprint> list = new List<Footprint>(); List<string> list2 = new List<string>(); BoatMooringRopes[] array = Resources.FindObjectsOfTypeAll<BoatMooringRopes>(); foreach (BoatMooringRopes val in array) { if ((Object)(object)val == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).isLoaded || !((Component)val).gameObject.activeInHierarchy) { continue; } Rigidbody component = ((Component)val).GetComponent<Rigidbody>(); SaveableObject component2 = ((Component)val).GetComponent<SaveableObject>(); if ((Object)(object)component == (Object)null || (Object)(object)component == (Object)(object)selected.Body || (Object)(object)component2 == (Object)null) { continue; } if (RootHulls(component, includeDisabled: false).Length != 1) { if (HasNearbyPhysicalBounds(component, own)) { throw new InvalidOperationException("Crab Beach hull clearance could not measure nearby boat " + ((Object)component).name + "."); } } else { list.Add(ReadHull(component, ((Component)component).transform.position, ((Component)component).transform.rotation)); list2.Add(((Object)component).name); } } Footprint[] others = list.ToArray(); int closest; float num = MinimumGap(own, others, Vector2.zero, out closest); if (num >= 1f) { return nativePosition; } Vector3 dock = (selected.Recovery.mooringFront.position + selected.Recovery.mooringBack.position) * 0.5f; if (!TryDirections(boatPos.right, boatPos.forward, boatPos.position, dock, out var outward, out var rear)) { throw new InvalidOperationException("Crab Beach hull clearance could not verify the direction away from the dock."); } if (!TryOffset(own, others, outward, rear, out var delta, out var side, out var back, out var gap)) { throw new InvalidOperationException("Crab Beach hull clearance found no space within 12m sideways and 4m rearward; neighboring boats were left unchanged."); } Vector3 val2 = nativePosition + new Vector3(delta.x, 0f, delta.y); if (!Finite(val2)) { throw new InvalidOperationException("Crab Beach hull clearance produced an invalid position."); } Plugin.Instance?.DebugLog($"Crab Beach hull clearance: moved {side:F2}m away from dock and {back:F2}m rearward; blocker {list2[closest]}, capsule gap {num:F2}m -> {gap:F2}m. Dock and terrain clearance still require an in-game check."); return val2; } internal static CapsuleCollider[] RootHulls(Rigidbody body, bool includeDisabled) { return (from c in ((Component)body).GetComponents<CapsuleCollider>() where (Object)(object)c != (Object)null && !((Collider)c).isTrigger && (includeDisabled || (((Collider)c).enabled && (Object)(object)((Collider)c).attachedRigidbody == (Object)(object)body)) select c).ToArray(); } private static Footprint ReadHull(Rigidbody body, Vector3 position, Quaternion rotation) { //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_0033: 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) CapsuleCollider[] array = RootHulls(body, includeDisabled: false); if (array.Length != 1) { throw new InvalidOperationException("Crab Beach hull clearance requires one measurable root capsule on " + ((Object)body).name + "."); } CapsuleCollider val = array[0]; return MakeFootprint(position, rotation, ((Component)body).transform.lossyScale, val.center, val.radius, val.height, val.direction); } private static bool HasNearbyPhysicalBounds(Rigidbody body, Footprint own) { //IL_001a: 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_0038: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) float num = own.Radius + 1f + 12f + 4f; float num2 = Math.Min(own.A.x, own.B.x) - num; float num3 = Math.Max(own.A.x, own.B.x) + num; float num4 = Math.Min(own.A.y, own.B.y) - num; float num5 = Math.Max(own.A.y, own.B.y) + num; Collider[] componentsInChildren = ((Component)body).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if (val.enabled && !val.isTrigger && !((Object)(object)val.attachedRigidbody != (Object)(object)body)) { Bounds bounds = val.bounds; if (!Finite(((Bounds)(ref bounds)).min) || !Finite(((Bounds)(ref bounds)).max)) { throw new InvalidOperationException("Crab Beach hull clearance found invalid collider bounds on " + ((Object)body).name + "."); } if (((Bounds)(ref bounds)).max.x >= num2 && ((Bounds)(ref bounds)).min.x <= num3 && ((Bounds)(ref bounds)).max.z >= num4 && ((Bounds)(ref bounds)).min.z <= num5) { return true; } } } return false; } internal static Footprint MakeFootprint(Vector3 position, Quaternion rotation, Vector3 scale, Vector3 center, float radius, float height, int direction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0090: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_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_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) if (!Finite(position) || !Finite(scale) || !Finite(center) || !Finite(rotation.x) || !Finite(rotation.y) || !Finite(rotation.z) || !Finite(rotation.w) || !Finite(radius) || !Finite(height) || radius <= 0f || height <= 0f || direction < 0 || direction > 2 || scale.x == 0f || scale.y == 0f || scale.z == 0f) { throw new InvalidOperationException("Crab Beach hull capsule has invalid geometry."); } Vector3 val = (Vector3)(direction switch { 1 => Vector3.up, 0 => Vector3.right, _ => Vector3.forward, }); HullDimensions hullDimensions = Measure(scale, center, radius, height, direction); Vector3 val2 = position + rotation * hullDimensions.Center; Vector3 val3 = rotation * val * hullDimensions.HalfSegment; Vector3 val4 = val2 + val3; Vector3 val5 = val2 - val3; if (!Finite(val4) || !Finite(val5) || !Finite(hullDimensions.Radius) || hullDimensions.Radius <= 0f) { throw new InvalidOperationException("Crab Beach hull capsule overflowed its geometry."); } return new Footprint { A = new Vector2(val4.x, val4.z), B = new Vector2(val5.x, val5.z), Radius = hullDimensions.Radius }; } internal static HullDimensions Measure(CapsuleCollider capsule, Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Measure(scale, capsule.center, capsule.radius, capsule.height, capsule.direction); } internal static HullDimensions Measure(Vector3 scale, Vector3 center, float radius, float height, int direction) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) float num = Math.Max(Math.Abs(((Vector3)(ref scale))[(direction + 1) % 3]), Math.Abs(((Vector3)(ref scale))[(direction + 2) % 3])); float num2 = radius * num; float num3 = Math.Max(height * Math.Abs(((Vector3)(ref scale))[direction]), 2f * num2); return new HullDimensions { Center = Vector3.Scale(center, scale), Radius = num2, Length = num3, HalfSegment = Math.Max(0f, num3 * 0.5f - num2) }; } internal static bool TryDirections(Vector3 right, Vector3 forward, Vector3 marker, Vector3 dock, out Vector2 outward, out Vector2 rear) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0082: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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) outward = new Vector2(0f - right.x, 0f - right.z); rear = new Vector2(0f - forward.x, 0f - forward.z); if (!Finite(right) || !Finite(forward) || !Finite(marker) || !Finite(dock) || ((Vector2)(ref outward)).sqrMagnitude < 0.5f || ((Vector2)(ref rear)).sqrMagnitude < 0.5f) { return false; } ((Vector2)(ref outward)).Normalize(); ((Vector2)(ref rear)).Normalize(); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(dock.x - marker.x, dock.z - marker.z); if (((Vector2)(ref val)).sqrMagnitude > 0.01f) { return Vector2.Dot(outward, ((Vector2)(ref val)).normalized) < -0.5f; } return false; } internal static bool TryOffset(Footprint own, Footprint[] others, Vector2 outward, Vector2 rear, out Vector2 delta, out float side, out float back, out float gap) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) //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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) delta = Vector2.zero; side = (back = 0f); gap = MinimumGap(own, others, delta, out var closest); if (gap >= 1f) { return true; } for (int i = 1; i <= 48; i++) { side = (float)i * 0.25f; back = Math.Min(side * 0.5f, 4f); delta = outward * side + rear * back; gap = MinimumGap(own, others, delta, out closest); if (gap >= 1f) { return true; } } return false; } internal static float MinimumGap(Footprint own, Footprint[] others, Vector2 delta, out int closest) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) float num = float.PositiveInfinity; closest = -1; for (int i = 0; i < others.Length; i++) { float num2 = SegmentDistance(own.A + delta, own.B + delta, others[i].A, others[i].B) - own.Radius - others[i].Radius; if (!Finite(num2)) { throw new InvalidOperationException("Crab Beach hull clearance could not measure a finite gap between boats."); } if (num2 < num) { num = num2; closest = i; } } return num; } internal static float SegmentDistance(Vector2 p, Vector2 q, Vector2 r, Vector2 s) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) //IL_0011: 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_0017: 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_0019: 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_0022: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_0170: Unknown result type (might be due to invalid IL or missing references) Vector2 val = q - p; Vector2 val2 = s - r; Vector2 val3 = p - r; double num = Vector2.Dot(val, val); double num2 = Vector2.Dot(val2, val2); double num3 = Vector2.Dot(val2, val3); if (num <= 1E-10 && num2 <= 1E-10) { return ((Vector2)(ref val3)).magnitude; } double num4; double num5; if (num <= 1E-10) { num4 = 0.0; num5 = Clamp(num3 / num2); } else { double num6 = Vector2.Dot(val, val3); if (num2 <= 1E-10) { num5 = 0.0; num4 = Clamp((0.0 - num6) / num); } else { double num7 = Vector2.Dot(val, val2); double num8 = num * num2 - num7 * num7; num4 = ((num8 > 1E-10) ? Clamp((num7 * num3 - num6 * num2) / num8) : 0.0); num5 = (num7 * num4 + num3) / num2; if (num5 < 0.0) { num5 = 0.0; num4 = Clamp((0.0 - num6) / num); } else if (num5 > 1.0) { num5 = 1.0; num4 = Clamp((num7 - num6) / num); } } } Vector2 val4 = p + val * (float)num4 - r - val2 * (float)num5; return ((Vector2)(ref val4)).magnitude; } private static double Clamp(double value) { return Math.Max(0.0, Math.Min(1.0, value)); } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (Finite(value.x) && Finite(value.y)) { return Finite(value.z); } return false; } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } public static class BoatNames { private sealed class Registration { internal PurchasableBoat Boat; internal string DisplayName; } private static readonly List<Registration> Registrations = new List<Registration>(); public static bool Register(PurchasableBoat boat, string displayName) { if ((Object)(object)boat == (Object)null || string.IsNullOrWhiteSpace(displayName)) { return false; } Prune(); string displayName2 = displayName.Trim(); Registration registration = Registrations.Find((Registration item) => item.Boat == boat); if (registration != null) { registration.DisplayName = displayName2; } else { Registrations.Add(new Registration { Boat = boat, DisplayName = displayName2 }); } return true; } internal static string DisplayName(PurchasableBoat boat, string fallback) { Prune(); Registration registration = (((Object)(object)boat == (Object)null) ? null : Registrations.Find((Registration item) => item.Boat == boat)); if (registration == null) { return fallback; } return registration.DisplayName; } private static void Prune() { Registrations.RemoveAll((Registration item) => (Object)(object)item.Boat == (Object)null); } } internal static class BoatSizing { internal static BoatSize? FromHull(float length, float radius) { float num = 2f * radius; if (float.IsNaN(length) || float.IsInfinity(length) || length <= 0f || float.IsNaN(num) || float.IsInfinity(num) || num <= 0f) { return null; } if (length <= 13f && num <= 4.4f) { return BoatSize.Small; } if (length <= 26f && num <= 6.8f) { return BoatSize.Medium; } return BoatSize.Large; } } internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public bool? HideDefaultButton; public bool? HideSettingName; public string DispName; public string Category; } internal sealed class ResolvedStart { public Port Port; public RecoveryPort Recovery; internal PortChoice Destination; internal StartBerthPlan Berth; internal bool UseShipyardBerth; public PurchasableBoat Boat; public SaveableObject Saveable; public Rigidbody Body; public BoatMooringRopes Ropes; public GPButtonDockMooring FrontMooring; public GPButtonDockMooring BackMooring; public StarterSet StarterSet; public StartMenu Menu; public int Region; public BoatSize? Size; internal StartingOptionsSettings Options; internal NativeBerth.Plan NativeBerth; internal Transform ShoreFrame { get { if (!((Object)(object)Recovery != (Object)null)) { return Destination?.DockRoot; } return ((Component)Recovery).transform; } } internal IslandHorizon Island { get { object obj = Destination?.Island; if (obj == null) { Port port = Port; if (port == null) { return null; } obj = ((Component)port).GetComponentInParent<IslandHorizon>(); } return (IslandHorizon)obj; } } } internal static class FixedStart { private sealed class RopePosition { public PickupableBoatMooringRope Rope; public Transform Parent; public Vector3 Position; public Quaternion Rotation; public GPButtonDockMooring Mooring; } private sealed class RopeCandidate { public PickupableBoatMooringRope Rope; public Vector3 LocalPosition; public float AlongHull; public float AcrossHull; } [HarmonyPatch(typeof(StartMenu), "ButtonClick", new Type[] { typeof(StartMenuButtonType) })] private static class ConfirmChoicePatch { private static bool Prefix(StartMenu __instance, StartMenuButtonType button) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)button != 7) { return true; } if (TryGetStartBlock(out var reason)) { MenuUi.ActiveFor(__instance)?.ShowBlockedStart(reason); return false; } ClearAcceptedButtonChoice(); Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null || !CanSelect) { return true; } MenuUi menuUi = null; try { menuUi = MenuUi.ActiveFor(__instance); if ((Object)(object)menuUi == (Object)null) { return true; } if (MenuAnimationsField?.GetValue(__instance) is int num && num > 0) { return true; } if (!menuUi.CanStart(out var reason2)) { menuUi.ShowBlockedStart(reason2); instance.Warn("New game blocked by New Beginnings selection: " + reason2); return false; } if (!instance.TryChooseStart(out var pair, out reason2)) { menuUi.ShowBlockedStart(reason2); instance.Warn("New game blocked by New Beginnings selection: " + reason2); return false; } if (!pair.Port.NeedsPlannedBerth && !pair.UseShipyardBerth && !TryResolve(pair.Port, pair.Boat.Index, pair.Boat.Size, out var _, out reason2)) { menuUi.ShowBlockedStart(reason2); instance.Warn("New game blocked by New Beginnings selection: " + reason2); return false; } if (!TryGetNativeStartActors(__instance, out var _, out var _)) { menuUi.ShowBlockedStart("The native player-start sequence is unavailable."); return false; } acceptedButtonPair = pair; acceptedButtonMenu = __instance; return true; } catch (Exception ex) { ClearAcceptedButtonChoice(); menuUi?.ShowBlockedStart(ex.Message); instance.Error("New Beginnings selection failed; the new game was not started.", ex); return false; } } private static void Postfix(StartMenu __instance) { if (acceptedButtonMenu == __instance) { ClearAcceptedButtonChoice(); } } } [HarmonyPatch(typeof(StartMenu), "StartNewGame")] [HarmonyBefore(new string[] { "com.nandbrew.scrambledseas" })] private static class BeginPatch { private static bool Prefix(StartMenu __instance) { if (TryGetStartBlock(out var _)) { return false; } StartPair startPair = ((acceptedButtonMenu == __instance) ? acceptedButtonPair : null); ClearAcceptedButtonChoice(); pending = null; pendingMenu = null; pendingOptions = null; CancelStartWork(); nativeTweenObserver = null; nativeTweenTarget = null; Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null || !CanSelect) { return true; } object obj = null; bool flag = false; try { StartPair pair = startPair; if (pair == null && !instance.TryChooseStart(out pair, out var reason2)) { instance.Error("New Beginnings could not choose a start for a new game it did not begin; that caller's start was left unchanged. " + reason2, null); return true; } obj = CurrentRegionField.GetValue(__instance); CurrentRegionField.SetValue(__instance, pair.Port.Region); flag = true; pending = pair; pendingMenu = __instance; pendingOptions = instance.StartOptions.Copy(); if (!pendingOptions.TryValidate(out var reason3)) { throw new InvalidOperationException(reason3); } pendingSnapshot = new StartSnapshot(__instance, (int)obj); flightGeneration = startGeneration; instance.Report($"New Beginnings selected port {pair.Port.Index} and boat scene {pair.Boat.Index}."); MarkStartSelected(); } catch (Exception ex) { ClearStartTiming(); pending = null; pendingMenu = null; pendingOptions = null; if (flag) { try { CurrentRegionField.SetValue(__instance, obj); } catch (Exception exception) { instance.Error("Native start region could not be restored after selection failed.", exception); } } CancelStart(); if (startPair == null) { instance.Error("New Beginnings could not prepare a start for a new game it did not begin; that caller's start was left unchanged.", ex); return true; } MenuUi.ActiveFor(__instance)?.ShowBlockedStart(ex.Message); instance.Error("The selected starting location could not be prepared. No regional start was substituted.", ex); return false; } return true; } private static Exception Finalizer(Exception __exception) { if (__exception != null) { CancelStartWork(); pending = null; pendingMenu = null; pendingOptions = null; } return __exception; } } [HarmonyPatch(typeof(StartMenu), "StartNewGame")] private static class EndPatch { private static void Postfix(StartMenu __instance) { if (pendingMenu == __instance) { CancelStart(); pending = null; pendingMenu = null; pendingOptions = null; Plugin.Instance?.Warn("New Beginnings selection was cleared because no player-start coroutine was created."); } } } [HarmonyPatch(typeof(StartMenu), "MovePlayerToStartPos")] private static class StartPositionPatch { private static bool Prefix(StartMenu __instance, ref IEnumerator __result) { if (TryPreparePendingStart(__instance, out var sequence)) { __result = sequence; return false; } return true; } } [HarmonyPatch] private static class NativeStartTweenPatch { private static MethodBase targetMethod; private static bool Prepare() { nativeTweenSeamReady = false; try { MethodInfo methodInfo = AccessTools.Method(typeof(StartMenu), "MovePlayerToStartPos", new Type[1] { typeof(Transform) }, (Type[])null); targetMethod = ((methodInfo != null) ? AccessTools.EnumeratorMoveNext((MethodBase)methodInfo) : null); } catch (Exception ex) { targetMethod = null; Plugin.Instance?.Warn("Native player-start iterator could not be inspected: " + ex.Message); } if (targetMethod != null) { return true; } Plugin.Instance?.Warn("Native player-start iterator is unavailable; the selected-port camera seam is disabled for this Sailwind build."); return false; } private static MethodBase TargetMethod() { return targetMethod; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> source) { //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown MethodInfo original = AccessTools.Method(typeof(Juicebox), "TweenPosition", new Type[4] { typeof(GameObject), typeof(Vector3), typeof(float), typeof(JuiceboxTween) }, (Type[])null); MethodInfo methodInfo = AccessTools.Method(typeof(FixedStart), "NativeStartTweenOrSnap", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FixedStart), "NativeStartAnimationSeconds", (Type[])null, (Type[])null); List<CodeInstruction> list = source.ToList(); CodeInstruction[] array = list.Where((CodeInstruction instruction) => (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, original)).ToArray(); List<int> list2 = new List<int>(); for (int num = 0; num < list.Count - 1; num++) { if (!(list[num].opcode != OpCodes.Ldc_R4) && list[num].operand is float num2 && (num2 == 7f || num2 == 1f) && !(list[num + 1].opcode != OpCodes.Stfld) && list[num + 1].operand is FieldInfo fieldInfo && fieldInfo.Name.Contains("<animTime>")) { list2.Add(num); } } if (original == null || methodInfo == null || methodInfo2 == null || array.Length != 1 || list2.Count != 2) { nativeTweenSeamReady = false; Plugin.Instance?.Warn("Native start tween and timing calls could not be isolated; Sailwind's original camera movement remains active."); return list; } array[0].opcode = OpCodes.Call; array[0].operand = methodInfo; foreach (int item in list2.OrderByDescending((int value) => value)) { list.Insert(item + 1, new CodeInstruction(OpCodes.Call, (object)methodInfo2)); } nativeTweenSeamReady = true; return list; } } [HarmonyPatch(typeof(SaveLoadManager), "LoadGame", new Type[] { typeof(int) })] private static class CancelBeforeLoad { private static void Prefix() { CancelStartWork("saved-game load"); } } [HarmonyPatch(typeof(StartMenu), "DisableIslandMenu")] private static class StartMenuHide { private static bool Prefix(StartMenu __instance) { if (pendingSnapshot != null) { return !pendingSnapshot.Hide(__instance); } return true; } } private sealed class StartSnapshot { private readonly StartMenu menu; private readonly Transform observer; private readonly Transform controller; private readonly Transform observerParent; private readonly Transform controllerParent; private readonly Vector3 observerLocal; private readonly Vector3 controllerLocal; private readonly Quaternion observerRotation; private readonly Quaternion controllerRotation; private readonly int[] currency; private readonly PortRegion region; private readonly int selectedRegion; private readonly int animations; private readonly CharacterController character; private readonly Behaviour movement; private readonly Behaviour mirror; private readonly bool characterEnabled; private readonly bool movementEnabled; private readonly bool mirrorEnabled; private readonly GameObject islandMenu; private readonly GameObject logo; private readonly bool logoActive; private readonly Vector3 islandMenuPosition; private readonly bool islandMenuActive; private readonly bool cursorEnabled; private readonly bool inCursorMenu; private readonly bool cursorVisible; private readonly bool pointerActive; private readonly CursorLockMode cursorLock; private readonly Transform pointer; private bool restored; internal StartSnapshot(StartMenu menu, int originalRegion) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) this.menu = menu; if (!TryGetNativeStartActors(menu, out observer, out var val)) { throw new InvalidOperationException("The native start actors are unavailable."); } controller = val.transform; character = val.GetComponent<CharacterController>(); ref Behaviour reference = ref movement; Component component = val.GetComponent("OVRPlayerController"); reference = (Behaviour)(object)((component is Behaviour) ? component : null); ref Behaviour reference2 = ref mirror; Component component2 = ((Component)observer).GetComponent("PlayerControllerMirror"); reference2 = (Behaviour)(object)((component2 is Behaviour) ? component2 : null); characterEnabled = (Object)(object)character != (Object)null && ((Collider)character).enabled; movementEnabled = (Object)(object)movement != (Object)null && movement.enabled; mirrorEnabled = (Object)(object)mirror != (Object)null && mirror.enabled; observerParent = observer.parent; controllerParent = controller.parent; observerLocal = observer.localPosition; controllerLocal = controller.localPosition; observerRotation = observer.localRotation; controllerRotation = controller.localRotation; currency = (int[])PlayerGold.currency.Clone(); region = GameState.newGameRegion; selectedRegion = originalRegion; animations = (int)MenuAnimationsField.GetValue(menu); ref GameObject reference3 = ref islandMenu; object? value = IslandMenuField.GetValue(menu); reference3 = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)islandMenu == (Object)null) { throw new InvalidOperationException("The native island menu is unavailable."); } islandMenuPosition = islandMenu.transform.localPosition; islandMenuActive = islandMenu.activeSelf; ref GameObject reference4 = ref logo; object? value2 = LogoField.GetValue(menu); reference4 = (GameObject)((value2 is GameObject) ? value2 : null); logoActive = (Object)(object)logo != (Object)null && logo.activeSelf; cursorEnabled = (bool)CursorEnabledField.GetValue(null); inCursorMenu = GameState.inCursorMenu; cursorVisible = Cursor.visible; cursorLock = Cursor.lockState; pointer = (Transform)(((Object)(object)MouseButtonPointer.instance != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); pointerActive = (Object)(object)pointer != (Object)null && ((Component)pointer).gameObject.activeSelf; } internal bool Hide(StartMenu owner) { if ((Object)(object)owner != (Object)(object)menu || (Object)(object)islandMenu == (Object)null) { return false; } islandMenu.SetActive(false); return true; } internal void Approach(PortChoice site) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) Vector3 position = site.Island.GetPosition(); position.y = 8f; observer.position = position; controller.position = position; } internal void Restore(string reason) { //IL_003f: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) if (restored) { return; } restored = true; if (GameState.currentlyLoading) { return; } if ((Object)(object)observer != (Object)null) { observer.SetParent(observerParent, false); observer.localPosition = observerLocal; observer.localRotation = observerRotation; } if ((Object)(object)controller != (Object)null) { controller.SetParent(controllerParent, false); controller.localPosition = controllerLocal; controller.localRotation = controllerRotation; } if ((Object)(object)character != (Object)null) { ((Collider)character).enabled = characterEnabled; } if ((Object)(object)movement != (Object)null) { movement.enabled = movementEnabled; } if ((Object)(object)mirror != (Object)null) { mirror.enabled = mirrorEnabled; } CursorEnabledField.SetValue(null, cursorEnabled); GameState.inCursorMenu = inCursorMenu; Cursor.visible = cursorVisible; Cursor.lockState = cursorLock; if ((Object)(object)pointer != (Object)null) { ((Component)pointer).gameObject.SetActive(pointerActive); } if ((Object)(object)logo != (Object)null) { logo.SetActive(logoActive); } if (PlayerGold.currency != null && PlayerGold.currency.Length == currency.Length) { Array.Copy(currency, PlayerGold.currency, currency.Length); } GameState.newGameRegion = region; if (!((Object)(object)menu == (Object)null) && !GameState.currentlyLoading) { CurrentRegionField.SetValue(menu, selectedRegion); MenuAnimationsField.SetValue(menu, animations); if ((Object)(object)islandMenu != (Object)null) { islandMenu.transform.localPosition = islandMenuPosition; islandMenu.SetActive(islandMenuActive); } CurrencySwitchButton masterButton = CurrencySwitchButton.masterButton; if (masterButton != null) { masterButton.ForceSetCurrency(selectedRegion); } MenuUi.ActiveFor(menu)?.ShowBlockedStart(reason); } } } private sealed class StartPlacement { internal readonly ResolvedStart Selected; private readonly StartMenu menu; private readonly Transform parent; private readonly Vector3 localPosition; private readonly Vector3 velocity; private readonly Vector3 angularVelocity; private readonly Quaternion localRotation; private readonly bool bodyKinematic; private readonly RopePosition[] ropePositions; private readonly Rigidbody anchorBody; private readonly Transform anchorParent; private readonly Vector3 anchorLocal; private readonly Vector3 anchorVelocity; private readonly Vector3 anchorAngularVelocity; private readonly Quaternion anchorRotation; private readonly Vector3 anchorBoatLocal; private readonly Quaternion anchorBoatRotation; private readonly float anchorLength; private readonly float anchorDrag; private readonly bool anchorKinematic; private readonly bool anchorWasSet; private readonly PurchasableBoat[] starters; private readonly Transform starterBoat; private readonly Transform lastBoat; private readonly Transform lastOwnedBoat; private readonly Port lastPort; private OffshoreHold offshoreHold; private PickupableBoatMooringRope frontRope; private PickupableBoatMooringRope backRope; private bool moved; private bool rolledBack; private bool changedNative; internal StartPlacement(ResolvedStart selected, StartMenu menu) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) Selected = selected; this.menu = menu; Rigidbody body = selected.Body; parent = ((Component)body).transform.parent; localPosition = ((Component)body).transform.localPosition; localRotation = ((Component)body).transform.localRotation; velocity = body.velocity; angularVelocity = body.angularVelocity; bodyKinematic = body.isKinematic; Anchor anchor = selected.Ropes.anchor; if ((Object)(object)anchor == (Object)null) { throw new InvalidOperationException("The native anchor is unavailable."); } anchorWasSet = anchor.IsSet(); anchorBody = ((Component)anchor).GetComponent<Rigidbody>(); if ((Object)(object)anchorBody == (Object)null) { throw new InvalidOperationException("The native anchor body is unavailable."); } anchorParent = ((Component)anchor).transform.parent; anchorLocal = ((Component)anchor).transform.localPosition; anchorRotation = ((Component)anchor).transform.localRotation; anchorBoatLocal = ((Component)body).transform.InverseTransformPoint(((Component)anchor).transform.position); anchorBoatRotation = Quaternion.Inverse(body.rotation) * anchorBody.rotation; anchorVelocity = anchorBody.velocity; anchorAngularVelocity = anchorBody.angularVelocity; anchorKinematic = anchorBody.isKinematic; anchorDrag = anchorBody.drag; anchorLength = anchor.GetRopeLength(); ropePositions = selected.Ropes.ropes.Select((PickupableBoatMooringRope rope) => new RopePosition { Rope = rope, Parent = ((Component)rope).transform.parent, Position = ((Component)rope).transform.localPosition, Rotation = ((Component)rope).transform.localRotation, Mooring = GetOriginalMooring(rope) }).ToArray(); starters = (PurchasableBoat[])StartingBoatsField.GetValue(menu); if (starters == null || selected.Region < 0 || selected.Region >= starters.Length) { throw new InvalidOperationException("The native regional starter array is incomplete."); } starterBoat = selected.StarterSet.starterBoat; lastBoat = GameState.lastBoat; lastOwnedBoat = GameState.lastOwnedBoat; lastPort = GameState.lastVisitedPort; } internal void Move() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) ResolvedStart s = Selected; if (s.Berth.Mode == StartBerthMode.Preserved) { return; } moved = true; if (anchorWasSet) { TryStartupSetup("release the starter anchor", delegate { ReleaseAnchorMethod.Invoke(s.Ropes.anchor, null); }); } TryStartupSetup("release the original moorings", (Action)s.Ropes.UnmoorAllRopes); TryStartupSetup("retract the starter anchor", delegate { s.Ropes.GetAnchorController().ResetAnchor(); }); ((Component)s.Body).transform.SetPositionAndRotation(s.Berth.Position, s.Berth.Rotation); s.Body.position = s.Berth.Position; s.Body.rotation = s.Berth.Rotation; s.Body.velocity = Vector3.zero; s.Body.angularVelocity = Vector3.zero; if (s.Berth.OffshoreHeld) { StowOffshoreAnchor(); if (s.Berth.Mode == StartBerthMode.ShipyardHeld && (Object)(object)s.Berth.FrontRope != (Object)null && (Object)(object)s.Berth.BackRope != (Object)null) { frontRope = s.Berth.FrontRope; backRope = s.Berth.BackRope; bool num = TryMoorAt(frontRope, s.FrontMooring, s.Body); bool flag = TryMoorAt(backRope, s.BackMooring, s.Body); if (num && flag) { s.Berth.Mode = StartBerthMode.Moored; } else { if (frontRope.IsMoored()) { TryStartupSetup("release an incomplete shipyard mooring", (Action)frontRope.Unmoor); } if (backRope.IsMoored()) { TryStartupSetup("release an incomplete shipyard mooring", (Action)backRope.Unmoor); } frontRope = null; backRope = null; } } if (s.Berth.OffshoreHeld) { offshoreHold = OffshoreHold.Attach(s.Body, s.Berth.Frame); } } else { anchorBody.position = ((Component)s.Body).transform.TransformPoint(anchorBoatLocal); frontRope = s.Berth.FrontRope; backRope = s.Berth.BackRope; if ((Object)(object)frontRope == (Object)null || (Object)(object)backRope == (Object)null) { TryStartupSetup("choose starter mooring ropes", delegate { ChooseMooringRopes(s, out frontRope, out backRope); }); } bool num2 = TryMoorAt(frontRope, s.FrontMooring, s.Body); bool flag2 = TryMoorAt(backRope, s.BackMooring, s.Body); if (!num2 || !flag2) { frontRope = null; backRope = null; } } anchorBody.velocity = Vector3.zero; anchorBody.angularVelocity = Vector3.zero; Physics.SyncTransforms(); } private void StowOffshoreAnchor() { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) ResolvedStart selected = Selected; Quaternion rotation = selected.Body.rotation * anchorBoatRotation; object? obj = AccessTools.Field(typeof(RopeControllerAnchor), "joint")?.GetValue(selected.Ropes.GetAnchorController()); ConfigurableJoint joint = (ConfigurableJoint)((obj is ConfigurableJoint) ? obj : null); if (!TryStowedPosition(selected.Body, anchorBody, joint, rotation, out var position)) { throw new InvalidOperationException("The native anchor joint cannot provide a finite stowed pose."); } anchorBody.rotation = rotation; anchorBody.position = position; anchorBody.velocity = Vector3.zero; anchorBody.angularVelocity = Vector3.zero; anchorBody.isKinematic = false; selected.Body.isKinematic = false; Physics.SyncTransforms(); } private static bool TryStowedPosition(Rigidbody hull, Rigidbody anchor, ConfigurableJoint joint, Quaternion rotation, out Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //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_005b: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) position = default(Vector3); if ((Object)(object)hull == (Object)null || (Object)(object)anchor == (Object)null || (Object)(object)joint == (Object)null || (Object)(object)((Component)joint).GetComponent<Rigidbody>() != (Object)(object)anchor || (Object)(object)((Joint)joint).connectedBody != (Object)(object)hull || !IsFinite(rotation)) { return false; } Vector3 val = ((Component)hull).transform.TransformPoint(((Joint)joint).connectedAnchor); Vector3 val2 = rotation * Vector3.Scale(((Joint)joint).anchor, ((Component)anchor).transform.lossyScale); position = val - val2; if (IsFinite(val) && IsFinite(val2)) { return IsFinite(position); } return false; } internal void ReleaseHull() { if (moved && (Object)(object)Selected.Body != (Object)null) { Selected.Body.isKinematic = bodyKinematic; } } internal bool Commit(out Transform target, out string reason) { //IL_008f: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00a6: Unknown result type (might be due to invalid IL or missing references) target = null; reason = null; try { ResolvedStart s = Selected; if (!StartDestinations.IsCurrent(s.Destination)) { reason = "the starting location is no longer loaded"; return false; } if (!NativeRecoveryReady(out var reason2)) { Plugin.Instance?.Warn(reason2 + " The start continues."); } Vector3 berthPosition = ((s.NativeBerth == null && (Object)(object)s.Recovery != (Object)null) ? s.Recovery.boatPos.position : s.Berth.Position); Transform playerTarget = StartArrival.MakeTarget(s, s.Berth.Rotation, s.Berth.ShorePosition, berthPosition); target = playerTarget; PurchasableBoat[] array = (PurchasableBoat[])starters.Clone(); array[s.Region] = s.Boat; changedNative = true; StartingBoatsField.SetValue(menu, array); s.StarterSet.starterBoat = ((Component)s.Saveable).transform; GameState.lastBoat = ((Component)s.Saveable).transform; GameState.lastOwnedBoat = ((Component)s.Saveable).transform; GameState.lastVisitedPort = s.Port; StarterOwnership.Arm(s); StartingValues.Arm(s); TryStartupSetup("track the player's landing", delegate { StartArrival.BeginTracking(menu, playerTarget); }); TryStartupSetup("prepare starter supplies", delegate { StarterCargo.Arm(s); }); if (s.Berth.Mode == StartBerthMode.Moored && (Object)(object)frontRope != (Object)null && (Object)(object)backRope != (Object)null) { TryStartupSetup("settle starter moorings", delegate { StarterMooring.Arm(menu, s, frontRope, backRope); }); } TryStartupSetup("schedule starter hull repair", delegate { StarterBoatRepair.Arm(menu, s); }); TryStartupSetup("prepare the starter rig", delegate { LeopardStarterRig.Arm(menu, s); }); return true; } catch (Exception ex) { reason = "Starting-location handoff failed: " + ex.Message; return false; } } internal void Rollback() { //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) if (rolledBack) { return; } rolledBack = true; OffshoreHold.Remove(offshoreHold); ResolvedStart selected = Selected; StarterOwnership.Cancel(selected); if (GameState.currentlyLoading) { return; } if (changedNative) { StartingBoatsField.SetValue(menu, starters); selected.StarterSet.starterBoat = starterBoat; GameState.lastBoat = lastBoat; GameState.lastOwnedBoat = lastOwnedBoat; GameState.lastVisitedPort = lastPort; } if (!moved || (Object)(object)selected.Body == (Object)null) { return; } if ((Object)(object)selected.Ropes != (Object)null) { selected.Ropes.UnmoorAllRopes(); } if ((Object)(object)selected.Ropes?.anchor != (Object)null && selected.Ropes.anchor.IsSet()) { ReleaseAnchorMethod.Invoke(selected.Ropes.anchor, null); } ((Component)selected.Body).transform.SetParent(parent, false); ((Component)selected.Body).transform.localPosition = localPosition; ((Component)selected.Body).transform.localRotation = localRotation; selected.Body.position = ((Component)selected.Body).transform.position; selected.Body.rotation = ((Component)selected.Body).transform.rotation; selected.Body.velocity = velocity; selected.Body.angularVelocity = angularVelocity; selected.Body.isKinematic = bodyKinematic; if ((Object)(object)anchorBody != (Object)null) { ((Component)anchorBody).transform.SetParent(anchorParent, false); ((Component)anchorBody).transform.localPosition = anchorLocal; ((Component)anchorBody).transform.localRotation = anchorRotation; anchorBody.position = ((Component)anchorBody).transform.position; anchorBody.rotation = ((Component)anchorBody).transform.rotation; anchorBody.velocity = anchorVelocity; anchorBody.angularVelocity = anchorAngularVelocity; anchorBody.isKinematic = anchorKinematic; anchorBody.drag = anchorDrag; } if ((Object)(object)selected.Ropes?.anchor != (Object)null && (!anchorWasSet || (Object)(object)anchorBody != (Object)null)) { selected.Ropes.anchor.OnLoad(anchorWasSet, anchorLength); } RopePosition[] array = ropePositions; foreach (RopePosition ropePosition in array) { if ((Object)(object)ropePosition.Rope == (Object)null) { continue; } try { if ((Object)(object)ropePosition.Mooring != (Object)null) { ropePosition.Rope.MoorTo(ropePosition.Mooring); continue; } ((Component)ropePosition.Rope).transform.SetParent(ropePosition.Parent, false); ((Component)ropePosition.Rope).transform.localPosition = ropePosition.Position; ((Component)ropePosition.Rope).transform.localRotation = ropePosition.Rotation; } catch (Exception ex) { Plugin.Instance?.Warn("An original mooring could not be restored: " + ex.Message); } } Physics.SyncTransforms(); } } private static readonly FieldInfo CurrentRegionField = AccessTools.Field(typeof(StartMenu), "currentRegion"); private static readonly FieldInfo StartingBoatsField = AccessTools.Field(typeof(StartMenu), "startingBoats"); private static readonly FieldInfo SaveableField = AccessTools.Field(typeof(PurchasableBoat), "saveable"); private static readonly FieldInfo PurchaseUiField = AccessTools.Field(typeof(PurchasableBoat), "purchaseUI"); private static readonly FieldInfo MooredSpringField = AccessTools.Field(typeof(PickupableBoatMooringRope), "mooredToSpring"); private static readonly FieldInfo RecoveryPortsField = AccessTools.Field(typeof(Recovery), "ports"); private static readonly FieldInfo PlayerObserverField = AccessTools.Field(typeof(StartMenu), "playerObserver"); private static readonly FieldInfo PlayerControllerField = AccessTools.Field(typeof(StartMenu), "playerController"); private static readonly FieldInfo MenuAnimationsField = AccessTools.Field(typeof(StartMenu), "animsPlaying"); private static StartPair pending; private static StartMenu pendingMenu; private static StartingOptionsSettings pendingOptions; private static StartPair acceptedButtonPair; private static StartMenu acceptedButtonMenu; private static GameObject nativeTweenObserver; private static Transform nativeTweenTarget; private static bool nativeTweenSeamReady; private static StartSnapshot pendingSnapshot; private static Action startCleanup; private static int startGeneration; private static int flightGeneration = -1; private static float startSelectedAt = -1f; private static readonly MethodInfo MovePlayerFactory = AccessTools.Method(typeof(StartMenu), "MovePlayerToStartPos", (Type[])null, (Type[])null); private static readonly MethodInfo ReleaseAnchorMethod = AccessTools.Method(typeof(Anchor), "ReleaseAnchor", (Type[])null, (Type[])null); private static readonly FieldInfo IslandMenuField = AccessTools.Field(typeof(StartMenu), "chooseIslandUI"); private static readonly FieldInfo LogoField = AccessTools.Field(typeof(StartMenu), "logo"); private static readonly FieldInfo CursorEnabledField = AccessTools.Field(typeof(MouseLook), "cursorEnabled"); private static readonly FieldInfo ControllerPointerField = AccessTools.Field(typeof(MouseButtonPointer), "controllerPointer"); internal static bool CanSelect { get { if (nativeTweenSeamReady && PlayerObserverField != null && PlayerControllerField != null) { return ScrambledSeasIntegration.CanSelect; } return false; } } internal static bool StartInFlight => flightGeneration == startGeneration; private static void ClearAcceptedButtonChoice() { acceptedButtonPair = null; acceptedButtonMenu = null; } internal static bool TryGetNativeStartActors(StartMenu menu, out Transform observer, out GameObject controller) { observer = null; controller = null; try { object? obj = PlayerObserverField?.GetValue(menu); observer = (Transform)((obj is Transform) ? obj : null); object? obj2 = PlayerControllerField?.GetValue(menu); controller = (GameObject)((obj2 is GameObject) ? obj2 : null); return (Object)(object)observer != (Object)null && (Object)(object)controller != (Object)null; } catch (Exception exception) { Plugin.Instance?.Error("Native start actor fields could not be read.", exception); return false; } } private static float NativeStartAnimationSeconds(float vanillaSeconds) { if (!((Object)(object)nativeTweenObserver != (Object)null)) { return vanillaSeconds; } return 0f; } private static void NativeStartTweenOrSnap(Juicebox tween, GameObject observer, Vector3 destination, float duration, JuiceboxTween easing) { //IL_0081: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)nativeTweenObserver != (Object)null && (Object)(object)observer == (Object)(object)nativeTweenObserver) { if ((Object)(object)nativeTweenTarget != (Object)null) { observer.transform.SetPositionAndRotation(nativeTweenTarget.position, nativeTweenTarget.rotation); } else { Plugin.Instance?.Warn("Selected player marker disappeared before the native camera tween; preserving the already teleported observer position."); } Plugin.Instance?.DebugLog("Suppressed native new-game camera tween for the selected port."); nativeTweenObserver = null; nativeTweenTarget = null; } else { tween.TweenPosition(observer, destination, duration, easing); } } private static void TeleportNativeStartObserver(StartMenu menu, Transform target) { //IL_0016: 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_0042: 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_0059: 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) try { if (!TryGetNativeStartActors(menu, out var observer, out var controller) || (Object)(object)target == (Object)null || !IsFinite(target.position) || !IsFinite(target.rotation)) { Plugin.Instance.Warn("Native start observer or target is unavailable; Sailwind's normal camera movement will run."); return; } observer.SetPositionAndRotation(target.position, target.rotation); controller.transform.SetPositionAndRotation(target.position, target.rotation); nativeTweenObserver = ((Component)observer).gameObject; nativeTweenTarget = target; Plugin.Instance.DebugLog("Native new-game observer and controller moved directly to the selected port."); } catch (Exception exception) { Plugin.Instance.Error("Could not move the native start camera directly; Sailwind's normal camera movement will run.", exception); } } private static bool IsFinite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } private static bool IsFinite(Quaternion value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown resu