Decompiled source of Untamo Boats v1.0.5
BepInEx/plugins/Untamo.Boats.dll
Decompiled 11 hours 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.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Connection; using FishNet.Object; using FishNet.Serializing; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Mathematics; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Untamo.Boats")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Untamo.Boats")] [assembly: AssemblyTitle("Untamo.Boats")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Untamo.Boats { [BepInPlugin("Untamo.Boats", "Untamo.Boats", "1.0.5")] public sealed class Plugin : BaseUnityPlugin { private readonly struct CollisionPair { internal readonly Collider Item; internal readonly Collider Boat; internal CollisionPair(Collider item, Collider boat) { Item = item; Boat = boat; } } public const string PluginGuid = "Untamo.Boats"; public const string PluginName = "Untamo.Boats"; public const string PluginVersion = "1.0.5"; private const int BoatCost = 250; private const int MaximumBoats = 10; private ConfigEntry<KeyboardShortcut> _purchaseKey; private ConfigEntry<KeyboardShortcut> _removeAllKey; private bool _purchaseInProgress; private Boat _activeBoat; private Harmony _harmony; private readonly Dictionary<string, Boat> _savedBoats = new Dictionary<string, Boat>(); private readonly HashSet<Boat> _restoringCustomBoats = new HashSet<Boat>(); private BoatSaveFile _save = new BoatSaveFile(); private string _savePath; private string _saveContextKey; private string _nextBoatName = "Custom Boat 1"; private bool _restoreStarted; private BoatManager _knownBoatManager; private float _nextAutoSave; private bool _hasRuntimeSpawnAnchor; private Vector3 _runtimeSpawnAnchor; private bool _isIslandTransition; private readonly List<CollisionPair> _ignoredHeldItemCollisions = new List<CollisionPair>(); private Component _collisionIgnoredItem; private Boat _collisionIgnoredBoat; private Boat _lastLocallyDrivenBoat; private bool _selectedMotorRestored; private bool _selectedSkinRestored; private bool _selectedControlSkinRestored; private Boat _selectedControlSkinRestoredBoat; private bool _selectedMotorMountRestored; private Boat _selectedMotorMountRestoredBoat; private Coroutine _selectedControlSkinRestoreRoutine; private bool _selectedRadarPositionRestored; private bool _originalHealthRestored; private bool _originalFuelRestored; private bool _originalCooknessRestored; private ILogHandler _previousUnityLogHandler; private GameObject _boostHudObject; private Component _boostTextComponent; private float _nextBoostHudRefresh; private float _nextNearbyBoatRefresh; private Boat _cachedNearbyBoat; private float _nextBoatCountRefresh; private int _cachedBoatCount; private float _nextOriginalBoatRefresh; private Boat _cachedOriginalBoat; private static int _drivenBoatCacheFrame = -1; private static Boat _cachedLocallyDrivenBoat; private float _interactionRecoveryHoldStart = -1f; private bool _interactionRecoveryTriggered; private const float DestructiveKeyHoldSeconds = 0.3f; private float _purchaseKeyHoldStart = -1f; private bool _purchaseKeyHoldTriggered; private float _removeAllKeyHoldStart = -1f; private bool _removeAllKeyHoldTriggered; private float _deleteKeyHoldStart = -1f; private bool _deleteKeyHoldTriggered; private float _insertKeyHoldStart = -1f; private bool _insertKeyHoldTriggered; private const float FuelSellHoldStepSeconds = 0.4f; private float _homeFuelHoldStart = -1f; private int _homeFuelSellSteps; internal static Plugin Instance { get; private set; } private void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown Instance = this; _purchaseKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "PurchaseBoatKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Buys and spawns a boat for 250. Up to four boats may exist."); _removeAllKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "RemoveAllBoatsKey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Despawns every boat and clears all saved purchased boats."); _saveContextKey = null; _savePath = Path.Combine(Paths.ConfigPath, "Untamo.Boats.pending.boats.txt"); _save = new BoatSaveFile(); BoatCruiseRouting.ConfigurePersistence(1f, RememberCruisePower); try { _previousUnityLogHandler = Debug.unityLogger.logHandler; if (!(_previousUnityLogHandler is SkinKeywordNoiseLogHandler)) { Debug.unityLogger.logHandler = (ILogHandler)(object)new SkinKeywordNoiseLogHandler(_previousUnityLogHandler); } } catch { _previousUnityLogHandler = null; } _harmony = new Harmony("Untamo.Boats"); _harmony.PatchAll(); BoatAdditionalDamageBridge.Install(_harmony, ((BaseUnityPlugin)this).Logger); BoatExactMeleeHitBridge.Install(_harmony, ((BaseUnityPlugin)this).Logger); BoatExactFistHitBridge.Install(_harmony, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press F8 to buy a boat for {2:N0}.", "Untamo.Boats", "1.0.5", 250)); } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } RestoreHeldItemCollisions(); if ((Object)(object)_boostHudObject != (Object)null) { Object.Destroy((Object)(object)_boostHudObject); } SaveBoats(); try { if (_previousUnityLogHandler != null && Debug.unityLogger.logHandler is SkinKeywordNoiseLogHandler) { Debug.unityLogger.logHandler = _previousUnityLogHandler; } } catch { } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: 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) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) EnsurePerGameSaveContext(); BoatManager instance = BoatManager.Instance; bool flag = (Object)(object)instance != (Object)(object)_knownBoatManager; if (flag) { if (_savedBoats.Count > 0 && _save != null && !string.IsNullOrEmpty(_savePath)) { SaveBoats(); } _knownBoatManager = instance; _restoreStarted = false; _selectedMotorRestored = false; _selectedSkinRestored = false; _selectedControlSkinRestored = false; _selectedControlSkinRestoredBoat = null; _selectedMotorMountRestored = false; _selectedMotorMountRestoredBoat = null; if (_selectedControlSkinRestoreRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_selectedControlSkinRestoreRoutine); _selectedControlSkinRestoreRoutine = null; } _selectedRadarPositionRestored = false; BoatMotorSkinRouting.ClearAllRuntime(); _originalHealthRestored = false; _originalFuelRestored = false; _originalCooknessRestored = false; _savedBoats.Clear(); _restoringCustomBoats.Clear(); if ((Object)(object)instance == (Object)null) { BoatGpsRouting.ClearRadarPositionRuntimeCache(); } if (InstanceFinder.IsServerStarted) { StopAllBoatInput(); } Boat locallyDrivenBoat = GetLocallyDrivenBoat(); if ((Object)(object)locallyDrivenBoat == (Object)null && (Object)(object)_lastLocallyDrivenBoat != (Object)null && ((NetworkBehaviour)_lastLocallyDrivenBoat).IsSpawned && (Object)(object)Player.LocalPlayer != (Object)null && InstanceFinder.IsServerStarted) { BoatManager.SetBoat(BoatInteractionRouting.GetManagerColliders(_lastLocallyDrivenBoat), _lastLocallyDrivenBoat); _lastLocallyDrivenBoat.TrySetDriver(Player.LocalPlayer); } } SyncDrivenBoatWithManager(); RestoreSelectedMotorIfNeeded(); RestoreSelectedMotorSkinIfNeeded(); RestoreSelectedSkinIfNeeded(); RestoreSelectedControlSkinIfNeeded(); RestoreSelectedMotorMountModeIfNeeded(); RestoreSelectedRadarPositionIfNeeded(); RestoreSelectedRadarSkinIfNeeded(); RestoreOriginalHealthIfNeeded(); RestoreOriginalFuelIfNeeded(); BoatCommandRouting.UpdatePendingResets(); UpdateIslandAnchor(); UpdateBoatInventoryControls(); UpdateBoatMotorAndGpsControls(); UpdateHeldItemBoatCollisions(); UpdateBoatBoostSelection(); BoatHitboxRouting.Update(); BoatDamageRouting.Update(); BoatDiscNativeCollisionPatch.UpdateThrowState(); BoatDamageVisualRouting.Update(); BoatMotorSkinRouting.Update(); BoatControlSkinRouting.Update(); BoatRadarSkinRouting.Update(); BoatFuelRouting.Update(); BoatCooknessInspectRouting.Update(); BoatPhysicsKeepAlive.Update(); BoatInteractionRouting.Update(); BoatClosestPhysicsRouting.Update(); UpdateInteractionRecoveryHold(); Boat locallyDrivenBoat2 = GetLocallyDrivenBoat(); if ((Object)(object)locallyDrivenBoat2 != (Object)null && Input.GetKey((KeyCode)308)) { bool key = Input.GetKey((KeyCode)304); if (Input.GetKeyDown((KeyCode)276)) { MoveRadarAndSave(locallyDrivenBoat2, new Vector3(0f, 0f, -0.1f)); } else if (Input.GetKeyDown((KeyCode)275)) { MoveRadarAndSave(locallyDrivenBoat2, new Vector3(0f, 0f, 0.1f)); } else if (Input.GetKeyDown((KeyCode)273)) { MoveRadarAndSave(locallyDrivenBoat2, key ? new Vector3(0f, 0.1f, 0f) : new Vector3(-0.1f, 0f, 0f)); } else if (Input.GetKeyDown((KeyCode)274)) { MoveRadarAndSave(locallyDrivenBoat2, key ? new Vector3(0f, -0.1f, 0f) : new Vector3(0.1f, 0f, 0f)); } } if ((Object)(object)locallyDrivenBoat2 != (Object)null) { _lastLocallyDrivenBoat = locallyDrivenBoat2; } else if (!flag && !_isIslandTransition) { _lastLocallyDrivenBoat = null; } KeyboardShortcut value; if (!_purchaseInProgress) { value = _purchaseKey.Value; if (IsHoldKeyTriggered(((KeyboardShortcut)(ref value)).MainKey, ref _purchaseKeyHoldStart, ref _purchaseKeyHoldTriggered, 0.3f)) { ((MonoBehaviour)this).StartCoroutine(TryPurchaseBoat()); } } value = _removeAllKey.Value; if (IsHoldKeyTriggered(((KeyboardShortcut)(ref value)).MainKey, ref _removeAllKeyHoldStart, ref _removeAllKeyHoldTriggered, 0.3f)) { RemoveAllBoats(); } if (IsHoldKeyTriggered((KeyCode)127, ref _deleteKeyHoldStart, ref _deleteKeyHoldTriggered, 0.3f)) { RemoveCurrentBoat(); } if (IsHoldKeyTriggered((KeyCode)277, ref _insertKeyHoldStart, ref _insertKeyHoldTriggered, 0.3f)) { TryRepairNearbyBoat(); } UpdateHomeFuelBuySellControl(); if ((Object)(object)locallyDrivenBoat2 != (Object)null && (Object)(object)BoatManager.Instance != (Object)null && (Object)(object)BoatManager.Boat != (Object)(object)locallyDrivenBoat2) { BoatManager.SetBoat(BoatInteractionRouting.GetManagerColliders(locallyDrivenBoat2), locallyDrivenBoat2); } if (!_restoreStarted && !string.IsNullOrEmpty(_saveContextKey) && !string.IsNullOrEmpty(_savePath) && InstanceFinder.IsServerStarted && (Object)(object)BoatManager.Instance != (Object)null) { _restoreStarted = true; ((MonoBehaviour)this).StartCoroutine(RestoreSavedBoats()); } if (InstanceFinder.IsServerStarted && Time.unscaledTime >= _nextAutoSave) { _nextAutoSave = Time.unscaledTime + 5f; SaveBoats(); } } private void LateUpdate() { BoatCruiseRouting.UpdatePersistentCruise(); BoatSkinRouting.UpdateCustomSkins(); BoatSkinRouting.UpdateRainbowSkins(); } private void FixedUpdate() { BoatFollowRouting.Update(); BoatAnchorRouting.FixedUpdate(); BoatDamageRouting.FixedUpdate(); } private void UpdateHomeFuelBuySellControl() { if (Input.GetKeyDown((KeyCode)278)) { _homeFuelHoldStart = Time.unscaledTime; _homeFuelSellSteps = 0; } if (Input.GetKey((KeyCode)278) && _homeFuelHoldStart >= 0f) { float num = Mathf.Max(0f, Time.unscaledTime - _homeFuelHoldStart); int num2 = Mathf.FloorToInt(num / 0.4f); while (_homeFuelSellSteps < num2) { _homeFuelSellSteps++; TrySellFuelNearbyBoat(); } } if (Input.GetKeyUp((KeyCode)278)) { if (_homeFuelHoldStart >= 0f && _homeFuelSellSteps == 0) { TryBuyFuelNearbyBoat(); } _homeFuelHoldStart = -1f; _homeFuelSellSteps = 0; } } private void TrySellFuelNearbyBoat() { if (!InstanceFinder.IsServerStarted) { return; } Boat val = GetLocallyDrivenBoat(); if ((Object)(object)val == (Object)null) { val = GetCachedNearbyBoat(); } if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsSpawned) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Move close to a boat before holding Home to sell fuel."); return; } float fuel = BoatFuelRouting.GetFuel(val); float num = Mathf.Round(fuel * 100f) / 100f; if (num < 0.5f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Boat needs at least {0.5f:0.00} Liter of fuel to sell. Fuel: {num:0.00} / 5 Liter."); return; } float fuel2 = Mathf.Max(0f, num - 0.5f); BoatFuelRouting.SetFuel(val, fuel2); if ((Object)(object)MoneyManager.Instance != (Object)null) { MoneyManager.AddMoney(1, Player.LocalPlayer); } SaveBoats(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Sold {0.5f:0.00} Liter of boat fuel for {1} game money. Fuel: {BoatFuelRouting.GetFuel(val):0.##} / 5 Liter."); } private void TryBuyFuelNearbyBoat() { if (!InstanceFinder.IsServerStarted) { return; } Boat val = GetLocallyDrivenBoat(); if ((Object)(object)val == (Object)null) { val = GetCachedNearbyBoat(); } if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsSpawned) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Move close to a boat before tapping Home to buy fuel."); return; } float fuel = BoatFuelRouting.GetFuel(val); float num = Mathf.Round(fuel * 100f) / 100f; if (num > 4.5f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Boat fuel is above 4.50 Liter, so no more fuel can be purchased."); return; } if (num >= 5f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Boat fuel tank is already full at 5 Liter."); return; } if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(1)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"You need 1 game money to buy 0.50 Liter of boat fuel."); return; } int money = MoneyManager.Money; MoneyManager.RemoveMoney(1, Player.LocalPlayer); int num2 = money - 1; if (MoneyManager.Money < num2) { int num3 = num2 - MoneyManager.Money; MoneyManager.AddMoney(num3, (Player)null); } BoatFuelRouting.SetFuel(val, Mathf.Min(5f, num + 0.5f)); SaveBoats(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Bought {0.5f:0.##} Liter of boat fuel for {1} game money. Fuel: {BoatFuelRouting.GetFuel(val):0.##} / 5 Liter."); } private void TryRepairNearbyBoat() { if (!InstanceFinder.IsServerStarted) { return; } Boat val = GetLocallyDrivenBoat(); if ((Object)(object)val == (Object)null) { val = GetCachedNearbyBoat(); } if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsSpawned) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Move close to a boat before pressing Insert to repair it."); return; } if (BoatDamageRouting.IsSinking(val)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"This boat is already sinking and cannot be repaired."); return; } float health = BoatDamageRouting.GetHealth(val); float num = Mathf.Max(0f, 7500f - health); if (num <= 0.01f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Boat health is already 7500. No repair needed and no money was charged."); return; } int boatRepairCost = GetBoatRepairCost(val); if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(boatRepairCost)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"You need {boatRepairCost:N0} game money to repair this boat."); return; } int money = MoneyManager.Money; MoneyManager.RemoveMoney(boatRepairCost, Player.LocalPlayer); int num2 = money - boatRepairCost; if (MoneyManager.Money < num2) { int num3 = num2 - MoneyManager.Money; MoneyManager.AddMoney(num3, (Player)null); } BoatDamageRouting.SetSavedHealth(val, 7500f); SaveBoats(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Boat repaired to 7500 health for {boatRepairCost:N0} game money."); } private IEnumerator TryPurchaseBoat() { _purchaseInProgress = true; if ((Object)(object)BoatManager.Instance == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boat manager is not ready. Unlock boats in the base game first."); _purchaseInProgress = false; yield break; } if (!InstanceFinder.IsServerStarted) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"The FishNet server is not running. In multiplayer, press F8 on the host."); _purchaseInProgress = false; yield break; } if (!IsBaseGameBoatUnlocked()) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boats are not unlocked yet. Unlock the boat in the base game before using F8."); _purchaseInProgress = false; yield break; } Boat[] boatsBefore = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0); int purchaseCost = ((boatsBefore.Length != 0) ? 250 : 0); Boat steeringBoat = GetLocallyDrivenBoat(); if ((Object)(object)steeringBoat == (Object)null) { steeringBoat = GetCachedNearbyBoat(); } if (boatsBefore.Length != 0 && (Object)(object)steeringBoat == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Stand on/next to an existing boat or drive one before pressing F8."); _purchaseInProgress = false; yield break; } if (boatsBefore.Length >= 10) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"The maximum of {10} active boats has already been reached."); _purchaseInProgress = false; yield break; } if (purchaseCost > 0 && ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(purchaseCost))) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"You need {purchaseCost:N0} game money to buy a boat."); _purchaseInProgress = false; yield break; } object prefab = GetBoatPrefab(); if (prefab == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"The game's boat prefab could not be found."); _purchaseInProgress = false; yield break; } Vector3 spawnPosition = GetBoatSpawnPosition(steeringBoat); Boat spawnedBoat = TrySpawnExtraBoat(rotation: (!((Object)(object)steeringBoat != (Object)null)) ? SpawnManager.BoatSpawnRot : (((Object)(object)steeringBoat.HiddenPhysicsRig != (Object)null) ? steeringBoat.HiddenPhysicsRig.rotation : ((Component)steeringBoat).transform.rotation), prefab: (Boat)prefab, position: spawnPosition); for (int frame = 0; frame < 60; frame++) { if (IsNetworkSpawned(spawnedBoat)) { break; } yield return null; } bool spawned = IsNetworkSpawned(spawnedBoat); if (!spawned && (Object)(object)spawnedBoat != (Object)null) { Object.Destroy((Object)(object)((Component)spawnedBoat).gameObject); } if (!spawned) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boat spawn failed. In multiplayer, buy boats on the host. Solo games are supported."); _purchaseInProgress = false; yield break; } byte inheritedMotor = (((Object)(object)steeringBoat != (Object)null) ? steeringBoat.MotorIndex : (_save.hasSelectedMotor ? _save.selectedMotorIndex : spawnedBoat.MotorIndex)); bool inheritedRadarUnlocked = (Object)(object)steeringBoat != (Object)null && BoatGpsRouting.HasRadar(steeringBoat); bool inheritedRadarVisible = inheritedRadarUnlocked && BoatGpsRouting.IsVisible(steeringBoat); byte inheritedMotorSkin = (((Object)(object)steeringBoat != (Object)null) ? BoatMotorSkinRouting.GetSkinIndex(steeringBoat) : byte.MaxValue); byte inheritedMotorFinish = (byte)(((Object)(object)steeringBoat != (Object)null) ? BoatMotorSkinRouting.GetFinishMode(steeringBoat) : (_save.hasSelectedMotorFinish ? _save.selectedMotorFinish : 0)); byte inheritedRadarSkin = (((Object)(object)steeringBoat != (Object)null) ? BoatRadarSkinRouting.GetSkinIndex(steeringBoat) : byte.MaxValue); byte inheritedControlSkin = (byte)(((Object)(object)steeringBoat != (Object)null) ? BoatControlSkinRouting.GetSkinIndex(steeringBoat) : (_save.hasSelectedControlSkin ? _save.selectedControlSkinIndex : 14)); byte inheritedHullSkin = (byte)(((Object)(object)steeringBoat != (Object)null) ? BoatSkinRouting.GetSkinIndex(steeringBoat) : (_save.hasSelectedSkin ? _save.selectedSkinIndex : 0)); byte inheritedHullStyle = (byte)(((Object)(object)steeringBoat != (Object)null) ? BoatSkinRouting.GetStyleMode(steeringBoat) : (_save.hasSelectedSkin ? _save.selectedSkinStyleMode : 0)); byte inheritedStripeSecondary = (byte)(((Object)(object)steeringBoat != (Object)null) ? BoatSkinRouting.GetStripeSecondarySkinIndex(steeringBoat) : (_save.hasSelectedSkin ? _save.selectedStripeSecondarySkinIndex : 14)); bool inheritedMotorMountUsesControls = (((Object)(object)steeringBoat != (Object)null) ? BoatControlSkinRouting.IsMotorMountUsingControls(steeringBoat) : (_save.hasSelectedMotorMountMode && _save.selectedMotorMountUsesControls)); Vector3 inheritedRadarOffset = (((Object)(object)steeringBoat != (Object)null) ? BoatGpsRouting.GetRadarOffset(steeringBoat) : Vector3.zero); EnsureBoatUnlocked(spawnedBoat); BoatGpsRouting.SetRadarUnlocked(spawnedBoat, inheritedRadarUnlocked); ActivateBoat(spawnedBoat); MotorRouting.ApplyMotor(spawnedBoat, inheritedMotor); BoatMotorSkinRouting.SetFinishMode(spawnedBoat, inheritedMotorFinish, reapplySkin: false); BoatMotorSkinRouting.ApplySkin(spawnedBoat, inheritedMotorSkin); BoatSkinRouting.SetSavedFinish(spawnedBoat, inheritedHullStyle); BoatSkinRouting.SetSavedStripeSecondarySkin(spawnedBoat, inheritedStripeSecondary); BoatSkinRouting.ApplySkin(spawnedBoat, inheritedHullSkin); BoatControlSkinRouting.SetMotorMountMode(spawnedBoat, inheritedMotorMountUsesControls, reapplyControls: false); if ((Object)(object)steeringBoat != (Object)null) { BoatControlSkinRouting.ApplySkin(spawnedBoat, inheritedControlSkin); } BoatGpsRouting.SetVisible(spawnedBoat, inheritedRadarVisible); BoatRadarSkinRouting.ApplySkin(spawnedBoat, inheritedRadarSkin); for (int inheritedRadarFrame = 0; inheritedRadarFrame < 120; inheritedRadarFrame++) { if (BoatGpsRouting.SetRadarOffset(spawnedBoat, inheritedRadarOffset)) { break; } yield return null; } if ((Object)(object)steeringBoat != (Object)null) { for (int skinReadyFrame = 0; skinReadyFrame < 120; skinReadyFrame++) { if (BoatSkinRouting.AreSkinRenderersReady(spawnedBoat)) { break; } yield return null; } BoatSkinRouting.SetSavedFinish(spawnedBoat, inheritedHullStyle); BoatSkinRouting.SetSavedStripeSecondarySkin(spawnedBoat, inheritedStripeSecondary); BoatSkinRouting.ApplySkin(spawnedBoat, inheritedHullSkin); BoatControlSkinRouting.SetMotorMountMode(spawnedBoat, inheritedMotorMountUsesControls, reapplyControls: false); BoatControlSkinRouting.ApplySkin(spawnedBoat, inheritedControlSkin); byte inheritedSkin = inheritedHullSkin; byte inheritedStyle = inheritedHullStyle; if ((inheritedStyle == 6 || inheritedStyle == 8) && inheritedSkin > 13) { for (int specialRetry = 0; specialRetry < 6; specialRetry++) { for (int settleFrame = 0; settleFrame < 15; settleFrame++) { yield return null; } if ((Object)(object)spawnedBoat == (Object)null || !((NetworkBehaviour)spawnedBoat).IsSpawned) { break; } BoatSkinRouting.SetSavedFinish(spawnedBoat, inheritedStyle); BoatSkinRouting.RebuildSavedSpecialFinishLikeManualSelection(spawnedBoat, inheritedSkin); } } } if ((Object)(object)steeringBoat != (Object)null) { for (int mountSettle = 0; mountSettle < 8; mountSettle++) { for (int mountWait = 0; mountWait < 5; mountWait++) { yield return null; } if ((Object)(object)spawnedBoat == (Object)null || !((NetworkBehaviour)spawnedBoat).IsSpawned) { break; } BoatControlSkinRouting.SetMotorMountMode(spawnedBoat, inheritedMotorMountUsesControls, reapplyControls: false); BoatControlSkinRouting.ApplySkin(spawnedBoat, inheritedControlSkin); } } BoatSkinRouting.SetSavedFinish(spawnedBoat, inheritedHullStyle); BoatSkinRouting.SetSavedStripeSecondarySkin(spawnedBoat, inheritedStripeSecondary); BoatSkinRouting.ApplySkin(spawnedBoat, inheritedHullSkin); BoatMotorSkinRouting.SetFinishMode(spawnedBoat, inheritedMotorFinish, reapplySkin: false); BoatMotorSkinRouting.ApplySkin(spawnedBoat, inheritedMotorSkin); BoatControlSkinRouting.SetMotorMountMode(spawnedBoat, inheritedMotorMountUsesControls, reapplyControls: false); BoatControlSkinRouting.ApplySkin(spawnedBoat, inheritedControlSkin); BoatRadarSkinRouting.ApplySkin(spawnedBoat, inheritedRadarSkin); BoatGpsRouting.SetVisible(spawnedBoat, inheritedRadarVisible); BoatGpsRouting.SetRadarOffset(spawnedBoat, inheritedRadarOffset); RememberSelectedMotor(inheritedMotor, saveImmediately: false); RememberSelectedRadar(inheritedRadarVisible, saveImmediately: false); RegisterPurchasedBoat(spawnedBoat); foreach (KeyValuePair<string, Boat> pair in _savedBoats) { if ((Object)(object)pair.Value != (Object)(object)spawnedBoat) { continue; } BoatSaveRecord newRecord = _save.boats.Find((BoatSaveRecord item) => item != null && item.id == pair.Key); if (newRecord != null) { newRecord.motorIndex = inheritedMotor; newRecord.skinIndex = inheritedHullSkin; newRecord.skinStyleMode = inheritedHullStyle; newRecord.stripeSecondarySkinIndex = inheritedStripeSecondary; newRecord.controlSkinIndex = BoatControlSkinRouting.NormalizeSkinIndex(inheritedControlSkin); newRecord.motorSkinIndex = BoatMotorSkinRouting.NormalizeSkinIndex(inheritedMotorSkin); newRecord.motorFinishMode = BoatMotorSkinRouting.NormalizeFinishMode(inheritedMotorFinish); newRecord.radarSkinIndex = BoatRadarSkinRouting.NormalizeSkinIndex(inheritedRadarSkin); newRecord.motorMountUsesControls = inheritedMotorMountUsesControls; newRecord.radarUnlocked = inheritedRadarUnlocked; newRecord.radarVisible = inheritedRadarVisible; newRecord.radarOffsetX = inheritedRadarOffset.x; newRecord.radarOffsetY = inheritedRadarOffset.y; newRecord.radarOffsetZ = inheritedRadarOffset.z; } break; } SaveBoats(); if (purchaseCost > 0) { int balanceBefore = MoneyManager.Money; MoneyManager.RemoveMoney(purchaseCost, Player.LocalPlayer); yield return null; int expectedBalance = balanceBefore - purchaseCost; if (MoneyManager.Money < expectedBalance) { int refund = expectedBalance - MoneyManager.Money; MoneyManager.AddMoney(refund, (Player)null); ((BaseUnityPlugin)this).Logger.LogWarning((object)$"The game removed too much money; Untamo.Boats refunded {refund:N0}."); } } if ((Object)(object)steeringBoat != (Object)null && (Object)(object)steeringBoat.Driver == (Object)(object)Player.LocalPlayer) { steeringBoat.TrySetDriver((Player)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Boat purchased for {purchaseCost:N0} and spawned near you at {spawnPosition}."); _purchaseInProgress = false; } private static bool IsBaseGameBoatUnlocked() { Boat boat = BoatManager.Boat; if ((Object)(object)boat != (Object)null && boat.BoatUnlocked) { return true; } object obj = AccessTools.Property(typeof(SaveManager), "CurServerSave")?.GetValue(null, null); if (obj != null && obj.GetType().GetField("UnlockedBoat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) is bool result) { return result; } return false; } private static void EnsureBoatUnlocked(Boat boat) { if ((Object)(object)boat == (Object)null) { return; } try { boat.UnlockBoat(); } catch { } if (boat.BoatUnlocked) { return; } PropertyInfo propertyInfo = AccessTools.Property(typeof(Boat), "BoatUnlocked"); if (propertyInfo != null && propertyInfo.CanWrite) { try { propertyInfo.SetValue(boat, true, null); } catch { } } FieldInfo[] fields = typeof(Boat).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { if (boat.BoatUnlocked) { break; } FieldInfo fieldInfo = fields[i]; string text = fieldInfo.Name.ToLowerInvariant(); if (!text.Contains("unlock") || text.Contains("radar")) { continue; } try { if (fieldInfo.FieldType == typeof(bool)) { fieldInfo.SetValue(boat, true); continue; } object value = fieldInfo.GetValue(boat); PropertyInfo propertyInfo2 = value?.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (propertyInfo2 != null && propertyInfo2.CanWrite && propertyInfo2.PropertyType == typeof(bool)) { propertyInfo2.SetValue(value, true, null); } } catch { } } } internal static Boat GetLocallyDrivenBoat() { int frameCount = Time.frameCount; if (_drivenBoatCacheFrame == frameCount) { if ((Object)(object)_cachedLocallyDrivenBoat != (Object)null && (Object)(object)_cachedLocallyDrivenBoat.Driver == (Object)(object)Player.LocalPlayer) { return _cachedLocallyDrivenBoat; } if ((Object)(object)_cachedLocallyDrivenBoat == (Object)null) { return null; } } _drivenBoatCacheFrame = frameCount; _cachedLocallyDrivenBoat = null; Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { return null; } Boat val = (((Object)(object)BoatManager.Instance == (Object)null) ? null : BoatManager.Boat); if ((Object)(object)val != (Object)null && (Object)(object)val.Driver == (Object)(object)localPlayer) { _cachedLocallyDrivenBoat = val; return val; } Boat[] array = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0); foreach (Boat val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.Driver == (Object)(object)localPlayer) { _cachedLocallyDrivenBoat = val2; return val2; } } return null; } internal static void InvalidateDrivenBoatCache() { _drivenBoatCacheFrame = -1; _cachedLocallyDrivenBoat = null; } private Boat GetCachedNearbyBoat() { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { _cachedNearbyBoat = null; return null; } if (Time.unscaledTime >= _nextNearbyBoatRefresh || (Object)(object)_cachedNearbyBoat == (Object)null || !((NetworkBehaviour)_cachedNearbyBoat).IsSpawned || (Object)(object)((Component)_cachedNearbyBoat).gameObject == (Object)null || !((Component)_cachedNearbyBoat).gameObject.activeInHierarchy) { _nextNearbyBoatRefresh = Time.unscaledTime + 0.15f; _cachedNearbyBoat = BoatClosestPhysicsRouting.FindNearestPhysicalBoat(localPlayer, 3.5f); } return _cachedNearbyBoat; } private int GetCachedBoatCount() { if (Time.unscaledTime >= _nextBoatCountRefresh) { _nextBoatCountRefresh = Time.unscaledTime + 1f; _cachedBoatCount = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0).Length; } return _cachedBoatCount; } private Boat GetCachedOriginalBoat() { HashSet<Boat> hashSet = new HashSet<Boat>(_savedBoats.Values); if (Time.unscaledTime < _nextOriginalBoatRefresh && (Object)(object)_cachedOriginalBoat != (Object)null && ((NetworkBehaviour)_cachedOriginalBoat).IsSpawned && (Object)(object)((Component)_cachedOriginalBoat).gameObject != (Object)null && ((Component)_cachedOriginalBoat).gameObject.activeInHierarchy && !hashSet.Contains(_cachedOriginalBoat) && !_restoringCustomBoats.Contains(_cachedOriginalBoat) && !IsSavedCustomBoatName(((Object)_cachedOriginalBoat).name)) { return _cachedOriginalBoat; } _nextOriginalBoatRefresh = Time.unscaledTime + 1f; _cachedOriginalBoat = null; Boat[] array = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0); foreach (Boat val in array) { if (!((Object)(object)val == (Object)null) && ((NetworkBehaviour)val).IsSpawned && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy && !hashSet.Contains(val) && !_restoringCustomBoats.Contains(val) && !IsSavedCustomBoatName(((Object)val).name)) { _cachedOriginalBoat = val; return val; } } return null; } private void SyncDrivenBoatWithManager() { Boat locallyDrivenBoat = GetLocallyDrivenBoat(); if (!((Object)(object)locallyDrivenBoat == (Object)null) && !BoatDamageRouting.IsSinking(locallyDrivenBoat) && !((Object)(object)BoatManager.Instance == (Object)null)) { if ((Object)(object)BoatManager.Boat != (Object)(object)locallyDrivenBoat) { BoatManager.SetBoat(BoatInteractionRouting.GetManagerColliders(locallyDrivenBoat), locallyDrivenBoat); } _activeBoat = locallyDrivenBoat; } } private void UpdateBoatInventoryControls() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 Boat locallyDrivenBoat = GetLocallyDrivenBoat(); Player localPlayer = Player.LocalPlayer; PlayerInventory val = (((Object)(object)localPlayer == (Object)null) ? null : localPlayer.Inventory); if ((Object)(object)locallyDrivenBoat == (Object)null || (Object)(object)val == (Object)null || (int)Cursor.lockState != 1) { return; } for (int i = 0; i < 8; i++) { if (Input.GetKeyDown((KeyCode)(49 + i))) { AccessTools.Method(typeof(PlayerInventory), "LocalTrySelectSlot", (Type[])null, (Type[])null)?.Invoke(val, new object[1] { i }); break; } } if (!Input.GetKeyDown((KeyCode)98)) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(PlayerInventory), "GetNextAvailableBait", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Server), "ChangeBait", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null || (Object)(object)Server.Instance == (Object)null) { return; } try { byte b = (byte)methodInfo.Invoke(val, new object[1] { false }); methodInfo2.Invoke(Server.Instance, new object[2] { localPlayer, b }); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not change bait while driving: " + ex.Message)); } } private static bool IsHoldKeyTriggered(KeyCode key, ref float holdStart, ref bool triggered, float requiredSeconds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKey(key)) { holdStart = -1f; triggered = false; return false; } if (triggered) { return false; } if (holdStart < 0f) { holdStart = Time.unscaledTime; return false; } if (Time.unscaledTime - holdStart < requiredSeconds) { return false; } triggered = true; return true; } private void UpdateInteractionRecoveryHold() { if (!Input.GetKey((KeyCode)101)) { _interactionRecoveryHoldStart = -1f; _interactionRecoveryTriggered = false; } else if (!_interactionRecoveryTriggered) { if (_interactionRecoveryHoldStart < 0f) { _interactionRecoveryHoldStart = Time.unscaledTime; } else if (!(Time.unscaledTime - _interactionRecoveryHoldStart < 3f)) { _interactionRecoveryTriggered = true; RecoverBoatInteractionState(); } } } private void RecoverBoatInteractionState() { Player localPlayer = Player.LocalPlayer; BoatManagerContactGuard.ClearAllExplicitSwitches(); Boat[] array = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0); if ((Object)(object)localPlayer != (Object)null) { foreach (Boat val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Driver != (Object)(object)localPlayer)) { StopBoatInputAndMotion(val, stopMotion: false); try { val.TrySetDriver((Player)null); } catch { } } } } BoatClosestPhysicsRouting.ClearContext(localPlayer); _lastLocallyDrivenBoat = null; if ((Object)(object)BoatManager.Instance != (Object)null) { try { BoatManager.SetBoat(Array.Empty<Collider>(), (Boat)null); } catch { } } BoatInteractionRouting.ForceRefresh(); BoatClosestPhysicsRouting.ForceRefresh(); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boat interaction state reset after holding E for 3 seconds."); } private void MoveRadarAndSave(Boat boat, Vector3 localDelta) { //IL_0012: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0130: 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) if ((Object)(object)boat == (Object)null) { return; } BoatGpsRouting.MoveRadar(boat, localDelta); Vector3 radarOffset = BoatGpsRouting.GetRadarOffset(boat); bool flag = false; foreach (Boat value2 in _savedBoats.Values) { if ((Object)(object)value2 == (Object)(object)boat) { flag = true; break; } } if (!flag) { _save.hasSelectedRadarPosition = true; _save.selectedRadarOffsetX = radarOffset.x; _save.selectedRadarOffsetY = radarOffset.y; _save.selectedRadarOffsetZ = radarOffset.z; _selectedRadarPositionRestored = false; } for (int i = 0; i < _save.boats.Count; i++) { if (_savedBoats.TryGetValue(_save.boats[i].id, out var value) && (Object)(object)value == (Object)(object)boat) { _save.boats[i].radarOffsetX = radarOffset.x; _save.boats[i].radarOffsetY = radarOffset.y; _save.boats[i].radarOffsetZ = radarOffset.z; break; } } SaveBoats(); } private void UpdateBoatMotorAndGpsControls() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Invalid comparison between Unknown and I4 Boat locallyDrivenBoat = GetLocallyDrivenBoat(); Boat val = locallyDrivenBoat; if ((Object)(object)val == (Object)null) { val = GetCachedNearbyBoat(); } if ((int)Cursor.lockState == 1 && Input.GetKeyDown((KeyCode)111) && (Object)(object)val != (Object)null) { BoatCruiseRouting.Toggle(val, ((BaseUnityPlugin)this).Logger); } if ((int)Cursor.lockState == 1 && (Object)(object)val != (Object)null && BoatCruiseRouting.EnabledFor(val)) { if (Input.GetKeyDown((KeyCode)280)) { BoatCruiseRouting.AdjustThrottle(val, 0.1f); } else if (Input.GetKeyDown((KeyCode)281)) { BoatCruiseRouting.AdjustThrottle(val, -0.1f); } } if ((int)Cursor.lockState == 1 && Input.GetKeyDown((KeyCode)112)) { if ((Object)(object)locallyDrivenBoat != (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Follow selection: exit the driver seat and stand on the boat you want to follow you, then press P."); } else { Boat boat = BoatClosestPhysicsRouting.FindNearestPhysicalBoat(Player.LocalPlayer, 3.5f); BoatFollowRouting.ToggleFollower(boat, ((BaseUnityPlugin)this).Logger); } } if ((int)Cursor.lockState == 1 && (Object)(object)locallyDrivenBoat == (Object)null && (Object)(object)val != (Object)null && BoatCruiseRouting.EnabledFor(val)) { float num = 0f; if (Input.GetKey((KeyCode)276)) { num -= 1f; } if (Input.GetKey((KeyCode)275)) { num += 1f; } if (!Mathf.Approximately(num, 0f)) { BoatCruiseRouting.AdjustAutopilotHeading(val, num * 55f * Time.unscaledDeltaTime); } } if ((int)Cursor.lockState != 1) { return; } Boat val2 = (((Object)(object)locallyDrivenBoat != (Object)null) ? locallyDrivenBoat : GetCachedNearbyBoat()); if ((Object)(object)val2 != (Object)null) { if (Input.GetKeyDown((KeyCode)291)) { BoatSkinRouting.DumpCustomSkinTargets(val2, ((BaseUnityPlugin)this).Logger); } MotorRouting.ObservePurchasedMotor(val2); int num2 = ((!Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)109)) ? ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)) : 0); if (num2 != 0 && MotorRouting.TryGetCycledMotor(val2, num2, out var motorIndex)) { if (InstanceFinder.IsServerStarted) { if (MotorRouting.ApplyMotor(val2, motorIndex)) { RememberSelectedMotor(motorIndex, saveImmediately: true); ((MonoBehaviour)this).StartCoroutine(ReapplyControlsAfterMotorChange(val2)); SaveBoats(); } } else if ((Object)(object)Server.Instance != (Object)null && (Object)(object)val2 == (Object)(object)locallyDrivenBoat) { RememberSelectedMotor(motorIndex, saveImmediately: true); Server.Instance.SetBoatSkin(MotorRouting.EncodeMotorRequest(motorIndex)); ((MonoBehaviour)this).StartCoroutine(ReapplyControlsAfterMotorChange(val2)); } } if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)109)) { int direction = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatMotorSkinRouting.TryGetCycledSkin(val2, direction, out var skinIndex) && BoatMotorSkinRouting.ApplySkin(val2, skinIndex)) { BoatControlSkinRouting.ApplySkin(val2, BoatControlSkinRouting.GetSkinIndex(val2)); RememberSelectedMotorSkin(val2); SaveBoats(); } } if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)106)) { int direction2 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatMotorSkinRouting.ToggleFinish(val2, direction2)) { RememberSelectedMotorSkin(val2); RememberMotorFinish(val2); SaveBoats(); } } if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)117) && !MotorRouting.HasNoMotor(val2) && BoatControlSkinRouting.ToggleMotorMountMode(val2)) { RememberMotorMountMode(val2); SaveBoats(); } if (!Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)106)) { int direction3 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatSkinRouting.ToggleFinish(val2, direction3, ((BaseUnityPlugin)this).Logger)) { RememberSelectedSkin(val2); SaveBoats(); } } if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)107)) { int direction4 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatControlSkinRouting.TryGetCycledSkin(val2, direction4, out var skinIndex2) && BoatControlSkinRouting.ApplySkin(val2, skinIndex2)) { RememberSelectedControlSkin(val2); RememberCustomBoatControlSkin(val2, skinIndex2); SaveBoats(); } } if (!Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)107)) { int direction5 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatSkinRouting.TryGetCycledSkin(val2, direction5, out var skinIndex3)) { BoatSkinRouting.ApplySkin(val2, skinIndex3); RememberSelectedSkin(val2); SaveBoats(); } } if (!Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)59)) { int direction6 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatSkinRouting.ToggleStripeSecondaryColor(val2, direction6, ((BaseUnityPlugin)this).Logger)) { RememberSelectedSkin(val2); SaveBoats(); } } } if ((Object)(object)val2 != (Object)null && Input.GetKeyDown((KeyCode)279)) { BoatAnchorRouting.Toggle(val2, ((BaseUnityPlugin)this).Logger); } if ((Object)(object)val2 != (Object)null && Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)103)) { int direction7 = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : (-1)); if (BoatRadarSkinRouting.TryGetCycledSkin(val2, direction7, out var skinIndex4) && BoatRadarSkinRouting.ApplySkin(val2, skinIndex4)) { RememberSelectedRadarSkin(val2); RememberCustomBoatRadarSkin(val2, skinIndex4); SaveBoats(); } } if ((Object)(object)locallyDrivenBoat == (Object)null) { return; } if (!Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)103)) { BoatGpsRouting.Toggle(locallyDrivenBoat, ((BaseUnityPlugin)this).Logger); RememberSelectedRadar(BoatGpsRouting.IsVisible(locallyDrivenBoat), saveImmediately: true); } if (Input.GetKeyDown((KeyCode)104)) { BoatHornRouting.Play(locallyDrivenBoat, ((BaseUnityPlugin)this).Logger); } if (((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)114)) || ((Input.GetKeyDown((KeyCode)306) || Input.GetKeyDown((KeyCode)305)) && Input.GetKey((KeyCode)114))) { if (InstanceFinder.IsServerStarted) { BoatCommandRouting.ResetToDefaultSpawn(locallyDrivenBoat); } else if ((Object)(object)Server.Instance != (Object)null) { Server.Instance.SetBoatSkin((byte)239); } } } private void UpdateBoatBoostSelection() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Boat locallyDrivenBoat = GetLocallyDrivenBoat(); Boat val = (((Object)(object)locallyDrivenBoat != (Object)null) ? locallyDrivenBoat : GetCachedNearbyBoat()); if ((Object)(object)val == (Object)null) { if ((Object)(object)_boostHudObject != (Object)null) { _boostHudObject.SetActive(false); } return; } EnsureBoostHud(); if ((Object)(object)_boostHudObject != (Object)null) { _boostHudObject.SetActive(true); } if (Time.unscaledTime >= _nextBoostHudRefresh) { _nextBoostHudRefresh = Time.unscaledTime + 0.2f; SetBoostHudText(val); } if (!((Object)(object)locallyDrivenBoat == (Object)null)) { float y = Input.mouseScrollDelta.y; if (!Mathf.Approximately(y, 0f)) { float num = ((y > 0f) ? 0.25f : (-0.25f)); BoatBoostRouting.SelectedMultiplier = Mathf.Clamp(BoatBoostRouting.SelectedMultiplier + num, 1.25f, 5f); _nextBoostHudRefresh = Time.unscaledTime + 0.2f; SetBoostHudText(val); } } } private void EnsureBoostHud() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_boostHudObject != (Object)null && (Object)(object)_boostTextComponent != (Object)null) { return; } Type type = FindRuntimeType("UnityEngine.Canvas"); Type type2 = FindRuntimeType("UnityEngine.UI.CanvasScaler"); Type type3 = FindRuntimeType("UnityEngine.UI.Text"); Type type4 = FindRuntimeType("UnityEngine.UI.Shadow"); Component val = FindNativeDamageTextTemplate(); Type type5 = (((Object)(object)val != (Object)null) ? ((object)val).GetType() : type3); if (type == null || type2 == null || type5 == null) { return; } _boostHudObject = new GameObject("Untamo Boat Boost HUD"); _boostHudObject.transform.SetParent((Transform)null, false); Object.DontDestroyOnLoad((Object)(object)_boostHudObject); Component target = _boostHudObject.AddComponent(type); SetEnumProperty(target, "renderMode", "ScreenSpaceOverlay"); SetRuntimeProperty(target, "sortingOrder", 4000); Component target2 = _boostHudObject.AddComponent(type2); SetEnumProperty(target2, "uiScaleMode", "ScaleWithScreenSize"); SetRuntimeProperty(target2, "referenceResolution", (object)new Vector2(1920f, 1080f)); GameObject val2 = new GameObject("Boat Boost Panel", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(_boostHudObject.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 1f); val3.anchorMax = new Vector2(0f, 1f); val3.pivot = new Vector2(0f, 1f); val3.anchoredPosition = new Vector2(20f, -20f); val3.sizeDelta = new Vector2(760f, 300f); GameObject val4 = new GameObject("Boat Boost Text", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val2.transform, false); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = new Vector2(0f, 1f); val5.anchorMax = Vector2.one; val5.pivot = new Vector2(0f, 1f); val5.anchoredPosition = Vector2.zero; val5.sizeDelta = new Vector2(760f, 290f); _boostTextComponent = val4.AddComponent(type5); if ((Object)(object)val != (Object)null) { CopyNativeDamageTextFont(val, _boostTextComponent); } else { object obj = FindNativeGameUiFont(); if (obj == null) { obj = typeof(Resources).GetMethod("GetBuiltinResource", new Type[2] { typeof(Type), typeof(string) })?.Invoke(null, new object[2] { FindRuntimeType("UnityEngine.Font"), "Arial.ttf" }); } SetRuntimeProperty(_boostTextComponent, "font", obj); } if (((object)_boostTextComponent).GetType().FullName != null && ((object)_boostTextComponent).GetType().FullName.StartsWith("TMPro.", StringComparison.Ordinal)) { SetRuntimeProperty(_boostTextComponent, "fontSize", 16f); SetEnumProperty(_boostTextComponent, "fontStyle", "Bold"); SetEnumProperty(_boostTextComponent, "alignment", "TopLeft"); SetRuntimeProperty(_boostTextComponent, "color", Color.white); SetRuntimeProperty(_boostTextComponent, "enableWordWrapping", false); SetRuntimeProperty(_boostTextComponent, "overflowMode", ParseEnumValue(_boostTextComponent, "overflowMode", "Overflow")); } else { SetRuntimeProperty(_boostTextComponent, "fontSize", 16); SetEnumProperty(_boostTextComponent, "fontStyle", "Bold"); SetEnumProperty(_boostTextComponent, "alignment", "UpperLeft"); SetRuntimeProperty(_boostTextComponent, "color", Color.white); SetEnumProperty(_boostTextComponent, "horizontalOverflow", "Overflow"); SetEnumProperty(_boostTextComponent, "verticalOverflow", "Overflow"); } SetRuntimeProperty(_boostTextComponent, "richText", true); SetRuntimeProperty(_boostTextComponent, "supportRichText", true); if (type4 != null) { Component target3 = val4.AddComponent(type4); SetRuntimeProperty(target3, "effectColor", (object)new Color(0f, 0f, 0f, 0.6f)); SetRuntimeProperty(target3, "effectDistance", (object)new Vector2(1.5f, -1.5f)); } Boat val6 = GetLocallyDrivenBoat(); if ((Object)(object)val6 == (Object)null) { val6 = GetCachedNearbyBoat(); } if ((Object)(object)val6 != (Object)null) { SetBoostHudText(val6); } } private static string GetFleetDriverNameFromSteamId(Player driver) { if ((Object)(object)driver == (Object)null) { return "Player"; } try { Type type = ((object)driver).GetType(); object obj = null; PropertyInfo property = type.GetProperty("SteamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { obj = property.GetValue(driver, null); } if (obj == null) { FieldInfo field = type.GetField("_steamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { obj = field.GetValue(driver); } } if (obj == null) { return "Player"; } Type type2 = Type.GetType("Steamworks.SteamFriends, com.rlabrecque.steamworks.net", throwOnError: false); if (type2 == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!(assembly == null)) { type2 = assembly.GetType("Steamworks.SteamFriends", throwOnError: false); if (type2 != null) { break; } } } } if (type2 == null) { return "Player"; } MethodInfo[] methods = type2.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo == null || methodInfo.Name != "GetFriendPersonaName") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters == null || parameters.Length != 1) { continue; } Type parameterType = parameters[0].ParameterType; object obj2 = obj; if (!parameterType.IsInstanceOfType(obj2)) { ulong num; try { num = Convert.ToUInt64(obj, CultureInfo.InvariantCulture); } catch { PropertyInfo property2 = obj.GetType().GetProperty("m_SteamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 == null) { continue; } num = Convert.ToUInt64(property2.GetValue(obj, null), CultureInfo.InvariantCulture); } try { obj2 = Activator.CreateInstance(parameterType, num); } catch { continue; } } string text = methodInfo.Invoke(null, new object[1] { obj2 }) as string; if (string.IsNullOrWhiteSpace(text)) { continue; } return text.Trim(); } } catch { } return "Player"; } private static string GetFleetFuelHudText(Boat boat) { float fuel = BoatFuelRouting.GetFuel(boat); string text = "Fuel: " + fuel.ToString("0.00", CultureInfo.InvariantCulture) + " L"; if (fuel >= 0.2f) { return text; } if (fuel <= 0.0001f) { return (((int)(Time.unscaledTime * 4f) & 1) == 0) ? ("<color=#FF3030>" + text + "</color>") : ("<color=#FF6B6B>" + text + "</color>"); } if (((int)(Time.unscaledTime * 4f) & 1) != 0) { return text; } return "<color=#FF6B6B>" + text + "</color>"; } private void SetBoostHudText(Boat selectedBoat) { if ((Object)(object)selectedBoat == (Object)null) { return; } int cachedBoatCount = GetCachedBoatCount(); string boatDisplayName = GetBoatDisplayName(selectedBoat); string visibilityText = BoatGpsRouting.GetVisibilityText(selectedBoat); string text = (BoatFollowRouting.IsSelectedFollower(selectedBoat) ? " | Follow Selected" : string.Empty); string stateText = BoatAnchorRouting.GetStateText(selectedBoat); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("\nFleet:"); Boat cachedOriginalBoat = GetCachedOriginalBoat(); if ((Object)(object)cachedOriginalBoat != (Object)null) { string value = (BoatDamageRouting.IsSinking(cachedOriginalBoat) ? "Sinking" : (BoatFollowRouting.IsSelectedFollower(cachedOriginalBoat) ? "Follow" : (BoatCruiseRouting.EnabledFor(cachedOriginalBoat) ? "Cruise" : ((!((Object)(object)cachedOriginalBoat.Driver != (Object)null)) ? "Idle" : ("Driving/" + GetFleetDriverNameFromSteamId(cachedOriginalBoat.Driver)))))); stringBuilder.Append("\n"); stringBuilder.Append(GetFleetBoatNameRichText(cachedOriginalBoat, "Original Boat")); stringBuilder.Append(" | "); stringBuilder.Append(value); stringBuilder.Append(" | "); stringBuilder.Append(GetFleetFuelHudText(cachedOriginalBoat)); stringBuilder.Append(" | Health: "); stringBuilder.Append(BoatDamageRouting.GetHealthText(cachedOriginalBoat)); } if (_save != null && _save.boats != null) { List<BoatSaveRecord> list = new List<BoatSaveRecord>(); for (int i = 0; i < _save.boats.Count; i++) { BoatSaveRecord boatSaveRecord = _save.boats[i]; if (boatSaveRecord != null) { Boat value2 = null; _savedBoats.TryGetValue(boatSaveRecord.id, out value2); if (!((Object)(object)value2 == (Object)null) && ((NetworkBehaviour)value2).IsSpawned && !((Object)(object)((Component)value2).gameObject == (Object)null) && ((Component)value2).gameObject.activeInHierarchy) { list.Add(boatSaveRecord); } } } list.Sort(delegate(BoatSaveRecord left, BoatSaveRecord right) { string strA = ((left == null || string.IsNullOrWhiteSpace(left.boatName)) ? string.Empty : left.boatName); string strB = ((right == null || string.IsNullOrWhiteSpace(right.boatName)) ? string.Empty : right.boatName); return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase); }); for (int num = 0; num < list.Count; num++) { BoatSaveRecord boatSaveRecord2 = list[num]; if (boatSaveRecord2 != null) { Boat value3 = null; _savedBoats.TryGetValue(boatSaveRecord2.id, out value3); if (!((Object)(object)value3 == (Object)null) && ((NetworkBehaviour)value3).IsSpawned && !((Object)(object)((Component)value3).gameObject == (Object)null) && ((Component)value3).gameObject.activeInHierarchy) { string value4 = (BoatDamageRouting.IsSinking(value3) ? "Sinking" : (BoatFollowRouting.IsSelectedFollower(value3) ? "Follow" : (BoatCruiseRouting.EnabledFor(value3) ? "Cruise" : ((!((Object)(object)value3.Driver != (Object)null)) ? "Idle" : ("Driving/" + GetFleetDriverNameFromSteamId(value3.Driver)))))); string boatName = (string.IsNullOrWhiteSpace(boatSaveRecord2.boatName) ? $"Custom Boat {num + 1}" : boatSaveRecord2.boatName); stringBuilder.Append("\n"); stringBuilder.Append(GetFleetBoatNameRichText(value3, boatName)); stringBuilder.Append(" | "); stringBuilder.Append(value4); stringBuilder.Append(" | "); stringBuilder.Append(GetFleetFuelHudText(value3)); stringBuilder.Append(" | Health: "); stringBuilder.Append(BoatDamageRouting.GetHealthText(value3)); } } } } SetRuntimeProperty(_boostTextComponent, "text", boatDisplayName + " | " + MotorRouting.GetDisplayName(selectedBoat) + " | Cruise " + BoatCruiseRouting.GetStateText(selectedBoat) + text + " | Anchor " + stateText + "\nBoat: Skin " + BoatSkinRouting.GetSkinDisplayName(selectedBoat) + BoatSkinRouting.GetStripeSecondaryHudText(selectedBoat) + BoatSkinRouting.GetFinishHudText(selectedBoat) + " | Motor: " + BoatMotorSkinRouting.GetHudDisplayName(selectedBoat) + " | Radar: " + BoatRadarSkinRouting.GetSkinDisplayName(selectedBoat) + " | Controls: Skin " + BoatControlSkinRouting.GetSkinDisplayName(selectedBoat) + "\n" + $"Boat Boost: {BoatBoostRouting.SelectedMultiplier:0.##}x | Speed: {BoatSpeedRouting.GetSpeedText(selectedBoat)} | Cruise Power: {BoatCruiseRouting.GetThrottleText(selectedBoat)}\n" + $"{cachedBoatCount}/{10} Boats" + stringBuilder.ToString()); } private static string GetFleetBoatNameRichText(Boat boat, string boatName) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(boatName) || (Object)(object)boat == (Object)null) { return boatName ?? string.Empty; } if (BoatSkinRouting.IsRainbowSkin(boat)) { return BoatFleetTextEffectRouting.BuildDripText(boatName); } if (!BoatSkinRouting.TryGetHudSkinColor(BoatSkinRouting.GetSkinIndex(boat), out var color)) { return boatName; } if (BoatSkinRouting.IsStripeStyle(boat)) { if (!BoatSkinRouting.TryGetHudSkinColor(BoatSkinRouting.GetStripeSecondarySkinIndex(boat), out var color2)) { color2 = color; } return BoatFleetTextEffectRouting.BuildAlternatingText(boatName, color, color2); } return BoatFleetTextEffectRouting.WrapColor(boatName, color); } internal string GetBoatDisplayName(Boat boat) { if ((Object)(object)boat == (Object)null) { return "Boat"; } foreach (KeyValuePair<string, Boat> pair in _savedBoats) { if (!((Object)(object)pair.Value != (Object)(object)boat)) { BoatSaveRecord boatSaveRecord = _save.boats.Find((BoatSaveRecord item) => item.id == pair.Key); if (boatSaveRecord != null && !string.IsNullOrWhiteSpace(boatSaveRecord.boatName)) { return boatSaveRecord.boatName; } } } return "Original Boat"; } private static Type FindRuntimeType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } return null; } private static Component FindNativeDamageTextTemplate() { Component[] array; try { array = Resources.FindObjectsOfTypeAll<Component>(); } catch { array = null; } if (array == null) { return null; } Component result = null; int num = 0; foreach (Component val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val.gameObject == (Object)null) { continue; } PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property2 = ((object)val).GetType().GetProperty("font", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || !property.CanWrite || property2 == null || !property2.CanRead) { continue; } int num2 = ScoreDamageTextComponent(val); if (num2 > num) { object obj2; try { obj2 = property2.GetValue(val, null); } catch { obj2 = null; } if (obj2 != null) { num = num2; result = val; } } } return result; } private static int ScoreDamageTextComponent(Component component) { if ((Object)(object)component == (Object)null) { return 0; } int num = 0; string text = ((object)component).GetType().Name.ToLowerInvariant(); if (text.Contains("textmeshpro")) { num += 10; } Transform val = component.transform; int num2 = 0; while ((Object)(object)val != (Object)null && num2 < 8) { string text2 = (((Object)(object)((Component)val).gameObject == (Object)null) ? string.Empty : ((Object)((Component)val).gameObject).name.ToLowerInvariant()); if (text2.Contains("damagenumber") || text2.Contains("damage number")) { num += 500; } if (text2.Contains("damage")) { num += 220; } if (text2.Contains("onhit")) { num += 300; } if (text2.Contains("hitmarker") || text2.Contains("hit marker")) { num += 180; } Component[] array; try { array = ((Component)val).GetComponents<Component>(); } catch { array = null; } if (array != null) { foreach (Component val2 in array) { if (!((Object)(object)val2 == (Object)null)) { string text3 = ((object)val2).GetType().Name.ToLowerInvariant(); if (text3 == "onhitui") { num += 700; } else if (text3.Contains("damagenumber")) { num += 600; } else if (text3.Contains("hitmarker")) { num += 300; } } } } val = val.parent; num2++; } return num; } private static void CopyNativeDamageTextFont(Component source, Component destination) { if ((Object)(object)source == (Object)null || (Object)(object)destination == (Object)null) { return; } string[] array = new string[3] { "font", "fontSharedMaterial", "fontMaterial" }; foreach (string name in array) { PropertyInfo property = ((object)source).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property2 = ((object)destination).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || property2 == null || !property.CanRead || !property2.CanWrite) { continue; } try { object value = property.GetValue(source, null); if (value != null && property2.PropertyType.IsInstanceOfType(value)) { property2.SetValue(destination, value, null); } } catch { } } } private static object FindNativeGameUiFont() { Component val = FindNativeDamageTextTemplate(); if ((Object)(object)val == (Object)null) { return null; } PropertyInfo property = ((object)val).GetType().GetProperty("font", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || !property.CanRead) { return null; } try { return property.GetValue(val, null); } catch { return null; } } private static object ParseEnumValue(object target, string propertyName, string value) { if (target == null) { return null; } PropertyInfo property = target.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || !property.PropertyType.IsEnum) { return null; } try { return Enum.Parse(property.PropertyType, value, ignoreCase: true); } catch { return Activator.CreateInstance(property.PropertyType); } } private static void SetRuntimeProperty(object target, string name, object value) { if (target == null || value == null) { return; } PropertyInfo property = target.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || !property.CanWrite) { return; } try { object obj = value; if (!property.PropertyType.IsInstanceOfType(obj) && obj is IConvertible && typeof(IConvertible).IsAssignableFrom(property.PropertyType)) { obj = Convert.ChangeType(obj, property.PropertyType, CultureInfo.InvariantCulture); } if (obj != null && property.PropertyType.IsInstanceOfType(obj)) { property.SetValue(target, obj, null); } } catch { } } private static void SetEnumProperty(object target, string name, string value) { if (target != null) { PropertyInfo property = target.GetType().GetProperty(name); if (!(property == null) && property.CanWrite && property.PropertyType.IsEnum) { property.SetValue(target, Enum.Parse(property.PropertyType, value, ignoreCase: true), null); } } } private void UpdateHeldItemBoatCollisions() { Boat locallyDrivenBoat = GetLocallyDrivenBoat(); Player localPlayer = Player.LocalPlayer; PlayerHolding val = (((Object)(object)localPlayer == (Object)null) ? null : localPlayer.Holding); Component val2 = (Component)(object)(((Object)(object)val == (Object)null) ? null : val.HeldItem); if ((Object)(object)locallyDrivenBoat == (Object)(object)_collisionIgnoredBoat && (Object)(object)val2 == (Object)(object)_collisionIgnoredItem) { return; } RestoreHeldItemCollisions(); if ((Object)(object)locallyDrivenBoat == (Object)null || (Object)(object)val2 == (Object)null) { return; } Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(); Collider[] managerColliders = BoatInteractionRouting.GetManagerColliders(locallyDrivenBoat); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] == (Object)null) { continue; } for (int j = 0; j < managerColliders.Length; j++) { if (!((Object)(object)managerColliders[j] == (Object)null)) { Physics.IgnoreCollision(componentsInChildren[i], managerColliders[j], true); _ignoredHeldItemCollisions.Add(new CollisionPair(componentsInChildren[i], managerColliders[j])); } } } _collisionIgnoredItem = val2; _collisionIgnoredBoat = locallyDrivenBoat; } private void RestoreHeldItemCollisions() { for (int i = 0; i < _ignoredHeldItemCollisions.Count; i++) { CollisionPair collisionPair = _ignoredHeldItemCollisions[i]; if ((Object)(object)collisionPair.Item != (Object)null && (Object)(object)collisionPair.Boat != (Object)null) { Physics.IgnoreCollision(collisionPair.Item, collisionPair.Boat, false); } } _ignoredHeldItemCollisions.Clear(); _collisionIgnoredItem = null; _collisionIgnoredBoat = null; } internal int GetBoatRepairCost(Boat boat) { if ((Object)(object)boat == (Object)null) { return 0; } float health = BoatDamageRouting.GetHealth(boat); float num = Mathf.Max(0f, 7500f - health); if (num <= 0.01f) { return 0; } bool flag = true; foreach (KeyValuePair<string, Boat> savedBoat in _savedBoats) { if ((Object)(object)savedBoat.Value == (Object)(object)boat) { flag = false; break; } } int num2 = (flag ? 190 : 240); return Mathf.Clamp(Mathf.CeilToInt(num / 7500f * (float)num2), 1, num2); } internal int GetBoatSellValue(Boat boat) { if ((Object)(object)boat == (Object)null) { return 0; } bool flag = false; foreach (KeyValuePair<string, Boat> savedBoat in _savedBoats) { if ((Object)(object)savedBoat.Value == (Object)(object)boat) { flag = true; break; } } if (!flag) { return 0; } float num = Mathf.Clamp(BoatDamageRouting.GetHealth(boat), 0f, 7500f); if (num <= 0f) { return 1; } return Mathf.Clamp(Mathf.CeilToInt(num / 7500f * 225f), 1, 225); } internal static int GetFuelSellRefundValue(Boat boat) { if ((Object)(object)boat == (Object)null) { return 0; } float fuel = BoatFuelRouting.GetFuel(boat); float num = Mathf.Round(fuel * 100f) / 100f; int num2 = Mathf.FloorToInt(num / 0.5f); return Mathf.Max(0, num2); } private void RemoveCurrentBoat() { Boat val = GetLocallyDrivenBoat(); if ((Object)(object)val == (Object)null) { val = GetCachedNearbyBoat(); } if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Delete ignored: drive a boat or stand on/next to one."); return; } if (!IsBaseGameBoatUnlocked()) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boats are not unlocked yet. Delete cannot remove boats until the base game boat is unlocked."); return; } string text = null; foreach (KeyValuePair<string, Boat> savedBoat in _savedBoats) { if ((Object)(object)savedBoat.Value == (Object)(object)val) { text = savedBoat.Key; break; } } if (string.IsNullOrEmpty(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"The original/base-game boat cannot be sold or deleted."); return; } int boatSellValue = GetBoatSellValue(val); int fuelSellRefundValue = GetFuelSellRefundValue(val); int num = boatSellValue + fuelSellRefundValue; _savedBoats.Remove(text); for (int num2 = _save.boats.Count - 1; num2 >= 0; num2--) { if (_save.boats[num2].id == text) { _save.boats.RemoveAt(num2); } } _nextBoatName = GetNextCustomBoatName(); RestoreHeldItemCollisions(); BoatGpsRouting.ClearExplicitRadarOwnership(val); BoatFollowRouting.ClearForBoat(val); BoatSkinRouting.ClearForBoat(val); BoatControlSkinRouting.ClearForBoat(val); BoatManagerContactGuard.ClearExplicitSwitch(val); try { if ((Object)(object)val.Driver == (Object)(object)Player.LocalPlayer) { val.TrySetDriver((Player)null); } } catch { } if ((Object)(object)BoatManager.Instance != (Object)null && (Object)(object)BoatManager.Boat == (Object)(object)val) { try { BoatManager.SetBoat(Array.Empty<Collider>(), (Boat)null); } catch { } } StopBoatInputAndMotion(val, stopMotion: false); if (InstanceFinder.IsServerStarted && ((NetworkBehaviour)val).IsSpawned) { try { InstanceFinder.ServerManager.Despawn(((Component)val).gameObject, (DespawnType?)null); } catch { Object.Destroy((Object)(object)((Component)val).gameObject); } } else if ((Object)(object)((Component)val).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } _lastLocallyDrivenBoat = null; _activeBoat = null; BoatClosestPhysicsRouting.ClearContext(Player.LocalPlayer); BoatInteractionRouting.ForceRefresh(); BoatClosestPhysicsRouting.ForceRefresh(); SaveBoats(); MoneyManager.AddMoney(num, Player.LocalPlayer); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Sold the currently driven boat for {boatSellValue} plus {fuelSellRefundValue} fuel money = {num} total."); } private void RemoveAllBoats() { if (!IsBaseGameBoatUnlocked()) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Boats are not unlocked yet. F9 cannot remove boats until the base game boat is unlocked."); return; } List<Boat> list = new List<Boat>(); foreach (KeyValuePair<string, Boat> savedBoat in _savedBoats) { Boat value = savedBoat.Value; if ((Object)(object)value != (Object)null) { list.Add(value); } } int num = 0; int num2 = 0; for (int i = 0; i < list.Count; i++) { Boat val = list[i]; if ((Object)(object)val == (Object)null) { continue; } bool flag = ((NetworkBehaviour)val).IsSpawned && (Object)(object)((Component)val).gameObject != (Object)null && ((Component)val).gameObject.activeInHierarchy; int num3 = (flag ? GetBoatSellValue(val) : 0); int num4 = (flag ? GetFuelSellRefundValue(val) : 0); BoatGpsRouting.ClearExplicitRadarOwnership(val); BoatManagerContactGuard.ClearExplicitSwitch(val); try { if ((Object)(object)val.Driver == (Object)(object)Player.LocalPlayer) { val.TrySetDriver((Player)null); } } catch { } StopBoatInputAndMotion(val, stopMotion: false); if (InstanceFinder.IsServerStarted && ((NetworkBehaviour)val).IsSpawned) { try { InstanceFinder.ServerManager.Despawn(((Component)val).gameObject, (DespawnType?)null); } catch { if ((Object)(object)((Component)val).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } else if ((Object)(object)((Component)val).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } if (flag) { num++; num2 += num3 + num4; } } _savedBoats.Clear(); _save.boats.Clear(); _nextBoatName = "Custom Boat 1"; _lastLocallyDrivenBoat = null; _activeBoat = null; BoatClosestPhysicsRouting.ClearContext(Player.LocalPlayer); BoatInteractionRouting.ForceRefresh(); BoatClosestPhysicsRouting.ForceRefresh(); SaveBoats(); if (num2 > 0) { MoneyManager.AddMoney(num2, Player.LocalPlayer); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Sold {num} spawned purchased boat(s) for {num2}. The original boat was kept."); } internal void HandleDestroyedBoatAfterSink(Boat boat) { if ((Object)(object)boat == (Object)null) { return; } bool flag = false; string text = null; foreach (KeyValuePair<string, Boat> savedBoat in _savedBoats) { if ((Object)(object)savedBoat.Value == (Object)(object)boat) { flag = true; text = savedBoat.Key; break; } } if (flag && !string.IsNullOrEmpty(text)) { _savedBoats.Remove(text); if (_save != null && _save.boats != null) { for (int num = _save.boats.Count - 1; num >= 0; num--) { if (_save.boats[num].id == text) { _save.boats.RemoveAt(num); } } } _nextBoatName = GetNextCustomBoatName(); } BoatGpsRouting.ClearExplicitRadarOwnership(boat); BoatFollowRouting.ClearForBoat(boat); BoatCruiseRouting.DisableForBoat(boat); BoatSkinRouting.ClearForBoat(boat); BoatManagerContactGuard.ClearExplicitSwitch(boat); try { if ((Object)(object)boat.Driver != (Object)null) { boat.TrySetDriver((Player)null); } } catch { } if ((Object)(object)BoatManager.Instance != (Object)null && (Object)(object)BoatManager.Boat == (Object)(object)boat) { try { BoatManager.SetBoat(Array.Empty<Collider>(), (Boat)null); } catch { } } BoatDamageRouting.ForgetBoat(boat); ForceRemoveBoat(boat); SaveBoats(); if (!flag) { ((MonoBehaviour)this).StartCoroutine(RespawnOriginalBoatAfterSink()); } } private void ChargeOriginalBoatRespawnFee() { int money = MoneyManager.Money; MoneyManager.RemoveMoney(200, Player.LocalPlayer); int num = money - 200; if (MoneyManager.Money < num) { int num2 = num - MoneyManager.Money; MoneyManager.AddMoney(num2, (Player)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Original boat reached 0 HP and respawned for 200 game money."); } private IEnumerator RespawnOriginalBoatAfterSink() { float readyAt = Time.unscaledTime + 1f; while (Time.unscaledTime < readyAt) { yield return null; } if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(200)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Original boat was destroyed, but you need 200 game money to respawn it. It will not respawn."); yield break; } for (int waitFrame = 0; waitFrame < 600; waitFrame++) { if (!InstanceFinder.IsServerStarted || (Object)(object)BoatManager.Instance == (Object)null) { yield return null; continue; } Boat existingOriginal = GetCachedOriginalBoat(); if ((Object)(object)existingOriginal != (Object)null && ((NetworkBehaviour)existingOriginal).IsSpawned) { PlaceOriginalBoatAtDefaultSpawn(existingOriginal); BoatDamageRouting.SetSavedHealth(existingOriginal, 7500f); BoatFuelRouting.SetFuel(existingOriginal, 1.5f); if (_save != null && _save.hasSelectedSkin) { BoatSkinRouting.SetSavedFinish(existingOriginal, _save.selectedSkinStyleMode); BoatSkinRouting.SetSavedStripeSecondarySkin(existingOriginal, _save.selectedStripeSecondarySkinIndex); BoatSkinRouting.ApplySkin(existingOriginal, _save.selectedSkinIndex); if ((_save.selectedSkinStyleMode == 6 || _save.selectedSkinStyleMode == 8) && _save.selectedSkinIndex > 13) { ((MonoBehaviour)this).StartCoroutine(RebuildOriginalSpecialFinishAfterLoad(existingOriginal, _save.selectedSkinIndex, _save.selectedSkinStyleMode)); } } ChargeOriginalBoatRespawnFee(); SaveBoats(); yield break; } object prefabObject = GetBoatPrefab(); if (!(prefabObject is Boat)) { yield return null; continue; } Boat replacement = TrySpawnExtraBoat((Boat)prefabObject, SpawnManager.BoatSpawnPos, SpawnManager.BoatSpawnRot); if ((Object)(object)replacement == (Object)null) { yield return null; continue; } for (int spawnFrame = 0; spawnFrame < 180; spawnFrame++) { if (((NetworkBehaviour)replacement).IsSpawned) { break; } yield return null; } if (!((NetworkBehaviour)replacement).IsSpawned) { if ((Object)(object)((Component)replacement).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)replacement).gameObject); } yield return null; continue; } PlaceOriginalBoatAtDefaultSpawn(replacement); EnsureBoatUnlocked(replacement); if (_save != null && _save.hasSelectedMotor) { MotorRouting.ApplyMotor(replacement, _save.selectedMotorIndex); } if (_save != null && _save.hasSelectedSkin) { BoatSkinRouting.SetSavedFinish(replacement, _save.selectedSkinStyleMode); BoatSkinRouting.SetSavedStripeSecondarySkin(replacement, _save.selectedStripeSecondarySkinIndex); BoatSkinRouting.ApplySkin(replacement, _save.selectedSkinIndex); if ((_save.selectedSkinStyleMode == 6 || _save.selectedSkinStyleMode == 8) && _save.selectedSkinIndex > 13) { ((MonoBehaviour)this).StartCoroutine(RebuildOriginalSpecialFinishAfterLoad(replacement, _save.selectedSkinIndex, _save.selectedSkinStyleMode)); } } BoatDamageRouting.SetSavedHealth(replacement, 7500f); BoatFuelRouting.SetFuel(replacement, 1.5f); _cachedOriginalBoat = replacement; _nextOriginalBoatRefresh = Time.unscaledTime + 1f; ChargeOriginalBoatRespawnFee(); SaveBoats(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Original boat respawned at its default game location after sinking."); yield break; } ((BaseUnityPlugin)this).Logger.LogWarning((object)"Original boat could not be respawned yet because the map/server boat prefab was not ready."); } private static void PlaceOriginalBoatAtDefaultSpawn(Boat boat) { //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_0019: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0070: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)boat == (Object)null)) { Vector3 boatSpawnPos = SpawnManager.BoatSpawnPos; Quaternion boatSpawnRot = SpawnManager.BoatSpawnRot; ((Component)boat).transform.SetPositionAndRotation(boatSpawnPos, boatSpawnRot); Rigidbody val = boat.HiddenPhysicsRig; if ((Object)(object)val == (Object)null) { val = ((Component)boat).GetComponentInChildren<Rigidbody>(); } if ((Object)(object)val != (Object)null) { val.position = boatSpawnPos; val.rotation = boatSpawnRot; val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; val.WakeUp(); } } } private static void ForceRemoveBoat(Boat boat) { if (!((Object)(object)boat == (Object)null)) { DespawnBoat(boat); if ((Object)(object)boat != (Object)null && (Object)(object)((Component)boat).gameObject != (Object)null) { ((Component)boat).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)boat).gameObject); } } } private static bool DespawnBoat(Boat boat) { if ((Object)(object)boat == (Object)null) { return false; } object networkObject = ((NetworkBehaviour)boat).NetworkObject; if (networkObject != null) { MethodInfo[] methods = networkObject.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (!(methods[i].Name != "Despawn")) { object[] parameters = BuildDefaultArguments(methods[i].GetParameters(), 0, null); try { methods[i].Invoke(networkObject, parameters); return true; } catch { } } } } MethodInfo[] methods2 = ((object)InstanceFinder.ServerManager).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int j = 0; j < methods2.Length; j++) { if (methods2[j].Name != "Despawn") { continue; } ParameterInfo[] parameters2 = methods2[j].GetParameters(); if (parameters2.Length == 0) { continue; } object obj2 = (parameters2[0].ParameterType.IsInstanceOfType(((Component)boat).gameObject) ? ((Component)boat).gameObject : (parameters2[0].ParameterType.IsInstanceOfType(networkObject) ? networkObject : null)); if (obj2 != null) { object[] parameters3 = BuildDefaultArguments(parameters2, 1, obj2); try { methods2[j].Invoke(InstanceFinder.ServerManager, parameters3); return true; } catch { } } } return false; } private static object[] BuildDefaultArguments(ParameterInfo[] parameters, int startIndex, object firstArgument) { object[] array = new object[parameters.Length]; if (startIndex == 1) { array[0] = firstArgument; } for (int i = startIndex; i < parameters.Length; i++) { if (parameters[i].HasDefaultValue) { array[i] = parameters[i].DefaultValue; } else if (parameters[i].ParameterType.IsValueType) { array[i] = Activator.CreateInstance(parameters[i].ParameterType); } else { array[i] = null; } } return array; } private void ActivateBoat(Boat boat) { if (!((Object)(object)boat == (Object)null)) { Collider[] managerColliders = BoatInteractionRouting.GetManagerColliders(boat); BoatManager.SetBoat(managerColliders, boat); _activeBoat = boat; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Active drivable boat changed to " + ((Object)boat).name + ".")); } } private static bool IsNetworkSpawned(Boat boat) { return (Object)(object)boat != (Object)null && (Object)(object)((Component)boat).gameObject != (Object)null && ((Component)boat).gameObject.activeInHierarchy && ((NetworkBehaviour)boat).IsSpawned; } private static Vector3 GetBoatSpawnPosition(Boat steeringBoat) { //IL_000c: 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_0039: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)steeringBoat == (Object)null) { return SpawnManager.BoatSpawnPos; } Vector3 val = (((Object)(object)steeringBoat.HiddenPhysicsRig != (Object)null) ? steeringBoat.HiddenPhysicsRig.position : ((Component)steeringBoat).transform.position); Quaternion val2 = (((Object)(object)steeringBoat.HiddenPhysicsRig != (Object)null) ? steeringBoat.HiddenPhysicsRig.rotation : ((Component)steeringBoat).transform.rotation); Vector3 val3 = val2 * Vector3.forward; Vector3 val4 = Vector3.ProjectOnPlane(val3, Vector3.up); val3 = ((Vector3)(ref val4)).normalized; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector3.forward; } return val + val3 * 10f; } private static Vector3 SeparateFromExistingBoats(Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_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_001c: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_00ee: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00d6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = SpawnManager.BoatSpawnRot * Vector3.right; Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up); val = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.right; } Boat[] array = Object.FindObjectsByType<Boat>((FindObjectsSortMode)0); for (int i = 0; i < 3; i++) { bool flag = false; for (int j = 0; j < array.Length; j++) { if (!((Object)(object)array[j] == (Object)null)) { Vector3 val3 = ((Component)array[j]).transform.position - position; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 9f) { flag = true; break; } } } if (!flag) { break; } position += val * 4f; } return position; } private Boat TrySpawnExtraBoat(Boat prefab, Vector3 position, Quaternion? rotation = null) { //IL_0002: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Boat val = Object.Instantiate<Boat>(prefab, position, (Quaternion)(((??)rotation) ?? SpawnManager.BoatSpawnRot)); if ((Object)(object)val == (Object)null) { return null; } try { InstanceFinder.ServerManager.Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene)); return val; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Object.Destroy((Object)(object)((Component)val).gameObject); return null; } } private static object GetBoatPrefab() { SpawnManager val = Object.FindAnyObjectByType<SpawnManager>(); if ((Object)(object)val == (Object)null) { return null; } return typeof(SpawnManager).GetField("_boatPrefab", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val); } private string GetNextCustomBoatName() { HashSet<int> hashSet = new HashSet<int>(); foreach (KeyValuePair<string, Boat> pair in _savedBoats) { Boat value = pair.Value; if ((Object)(object)value == (Object)null || !((NetworkBehaviour)value).IsSpawned || (Object)(object)((Component)value).gameObject == (Object)null || !((Component)value).gameObject.activeInHierarchy) { continue; } string name = ((Object)value).name; BoatSaveRecord boatSaveRecord = null; if (_save != null && _save.boats != null) { boatSaveRecord = _save.boats.Find((BoatSaveRecord item) => item.id == pair.Key); } if (boatSaveRecord != null && !string.IsNullOrWhiteSpace(boatSaveRecord.boatName)) { name = boatSaveRecord.boatName; } if (TryGetCustomBoatNumber(name, out var number)) { hashSet.Add(number); } } int num; for (num = 1; hashSet.Contains(num); num++) { } return $"Custom Boat {num}"; } private void EnsureUniqueCustomBoatNames() { if (_save == null || _save.boats == null) { return; } HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < _save.boats.Count; i++) { BoatSaveRecord boatSaveRecord = _save.boats[i]; if (TryGetCustomBoatNumber(boatSaveRecord.boatName, out var number) && !hashSet.Contains(number)) { hashSet.Add(number); boatSaveRecord.boatName = $"Custom Boat {number}"; continue; } int j; for (j = 1; hashSet.Contains(j); j++) { } hashSet.Add(j); boatSaveRecord.boatName = $"Custom Boat {j}"; } } private static string NormalizeCustomBoatName(string name, int fallbackNumber) { if (TryGetCustomBoatNumber(name, out var number)) { return $"Custom Boat {number}"; } return $"Custom Boat {Mathf.Max(1, fallbackNumber)}"; } private static bool TryGetCustomBoatNumber(string name, out int number) { number = 0; if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name.Trim(); string text2 = null; if (text.StartsWith("Custom Boat ", StringComparison.OrdinalIgnoreCase)) { text2 = text.Substring("Custom Boat ".Length); } else if (text.StartsWith("Boat ", StringComparison.OrdinalIgnoreCase)) { text2 = text.Substring("Boat ".Length); } if (text2 == null || !int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 1) { return false; } number = result; return true; } private void RegisterPurchasedBoat(Boat boat) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) string nextCustomBoatName = GetNextCustomBoatName(); BoatSaveRecord boatSaveRecord = new BoatSaveRecord { id = Guid.NewGuid().ToString("N"), ownerId = GetLocalOwnerId(), boatName = nextCustomBoatName, motorIndex = boat.MotorIndex, radarUnlocked = BoatGpsRouting.HasRadar(boat), radarVisible = BoatGpsRouting.IsVisible(boat), skinIndex = BoatSkinRouting.GetSkinIndex(boat), skinStyleMode = BoatSkinRouting.GetStyleMode(boat), stripeSecondarySkinIndex =