Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CrewManualSailControl v0.9.5
ManualSail.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ManualSail")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("ManualSail")] [assembly: AssemblyTitle("ManualSail")] [assembly: AssemblyVersion("0.1.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 ManualSail { [BepInPlugin("com.bouns.manualsail", "Manual Sail", "0.9.5")] public class Plugin : BaseUnityPlugin { internal sealed class OarCfg { public ConfigEntry<int> count; public ConfigEntry<float> side; public ConfigEntry<float> spacing; public ConfigEntry<float> height; public ConfigEntry<float> stand; public ConfigEntry<float> length; public ConfigEntry<float> width; } internal sealed class RowerState { public readonly Dictionary<long, float> beats = new Dictionary<long, float>(); } public const string GUID = "com.bouns.manualsail"; public const string NAME = "Manual Sail"; public const string VERSION = "0.9.5"; internal static ManualLogSource Log; internal const string ZKEY = "bouns_sailyaw"; internal const string RPC = "bouns_setsail"; internal const string RPC_ROW = "bouns_row"; internal const string ZKEY_ROWERS = "bouns_rowers"; internal const float ROW_ACCEL = 9.8f; private static readonly FieldInfo F_nview = AccessTools.Field(typeof(Ship), "m_nview"); private static readonly MethodInfo M_isSailUp = AccessTools.Method(typeof(Ship), "IsSailUp", (Type[])null, (Type[])null); private static readonly FieldInfo F_shipControlls = AccessTools.Field(typeof(Ship), "m_shipControlls"); private static readonly FieldInfo F_scAnim = AccessTools.Field(typeof(ShipControlls), "m_attachAnimation"); private static readonly FieldInfo F_scDetach = AccessTools.Field(typeof(ShipControlls), "m_detachOffset"); private static readonly FieldInfo F_scAttachPoint = AccessTools.Field(typeof(ShipControlls), "m_attachPoint"); internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyCode> KeyLeft; internal static ConfigEntry<KeyCode> KeyRight; internal static ConfigEntry<float> RotateSpeed; internal static ConfigEntry<float> MaxAngle; internal static ConfigEntry<float> MinEfficiency; internal static ConfigEntry<bool> Debug; internal static ConfigEntry<bool> OarsEnabled; internal static ConfigEntry<float> BonusUp; internal static ConfigEntry<float> BonusDown; private static readonly Dictionary<string, OarCfg> _oarCfg = new Dictionary<string, OarCfg>(); private Ship _editShip; private float _editYaw; private float _lastRpcYaw; private float _lastRpcTime; private bool _wasRowing; private Ship _rowShip; private float _lastRowBeat; internal static bool StationRowing; internal static Ship StationShip; internal static OarStation CurrentStation; private static readonly ConditionalWeakTable<Ship, RowerState> _rowers = new ConditionalWeakTable<Ship, RowerState>(); private static readonly List<long> _staleBuf = new List<long>(); private static Font _font; private static bool _fontTried; private const string Deg = "°"; private void Awake() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for the whole mod (manual sail + oars). false = vanilla."); KeyLeft = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RotateSailLeft", (KeyCode)276, "Hold to swing the sail to port (left)."); KeyRight = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RotateSailRight", (KeyCode)275, "Hold to swing the sail to starboard (right)."); RotateSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "RotateSpeedDegPerSec", 60f, new ConfigDescription("How fast the sail swings while a key is held.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 360f), Array.Empty<object>())); MaxAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "MaxAngleDeg", 90f, new ConfigDescription("Maximum swing to each side.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 90f), Array.Empty<object>())); MinEfficiency = ((BaseUnityPlugin)this).Config.Bind<float>("Sailing", "MinEfficiency", 0.25f, new ConfigDescription("Lowest wind efficiency, even with the sail badly trimmed or into the wind. 0 = you can be brought to a full stop. 0.25 = you always keep some way on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); Debug = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "Debug", false, "true = show a small sail angle and wind efficiency overlay while aboard a ship."); OarsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Oars", "Enabled", true, "Crew oars: players aboard can man an oar to add speed."); BonusUp = ((BaseUnityPlugin)this).Config.Bind<float>("Oars", "SpeedBonusPerRowerSailUp", 6f, new ConfigDescription("Speed bonus per active rower when the sail is up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>())); BonusDown = ((BaseUnityPlugin)this).Config.Bind<float>("Oars", "SpeedBonusPerRowerSailDown", 4f, new ConfigDescription("Speed bonus per active rower when the sail is down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>())); Bind("Raft", "Oars 1 Raft", 2, 1.2f, 1.2f, 0.8f, 0f, 1f, 1f); Bind("Karve", "Oars 2 Karve", 2, 0.8f, 3.5f, 0.3f, 0f, 1f, 1f); Bind("Longship", "Oars 3 Longship", 4, 2f, 4f, 1.2f, 0f, 1f, 1f); Bind("Drakkar", "Oars 4 Drakkar", 4, 3f, 9f, 2.4f, -2f, 1.6f, 1.6f); try { new Harmony("com.bouns.manualsail").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Manual Sail v0.9.5 loaded."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Manual Sail v0.9.5 FAILED to patch (Valheim version mismatch?): " + ex)); } void Bind(string key, string section, int cnt, float side, float sp, float h, float stand, float len, float wid) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown OarCfg value = new OarCfg { count = ((BaseUnityPlugin)this).Config.Bind<int>(section, "OarCount", cnt, new ConfigDescription("Number of oars (0 disables).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>())), side = ((BaseUnityPlugin)this).Config.Bind<float>(section, "SideOffset", side, new ConfigDescription("Distance from center to each side. Live.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 8f), Array.Empty<object>())), spacing = ((BaseUnityPlugin)this).Config.Bind<float>(section, "Spacing", sp, new ConfigDescription("Spacing along the hull between oars on the same side. Live.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>())), height = ((BaseUnityPlugin)this).Config.Bind<float>(section, "Height", h, new ConfigDescription("Oar visual height above the boat origin. Live.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 6f), Array.Empty<object>())), stand = ((BaseUnityPlugin)this).Config.Bind<float>(section, "StandOffset", stand, new ConfigDescription("Vertical offset for where the rower stands. Lower it if they float above the deck. Live.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3f, 3f), Array.Empty<object>())), length = ((BaseUnityPlugin)this).Config.Bind<float>(section, "OarLength", len, new ConfigDescription("Oar length multiplier (extends the blade end). Applied when the boat loads.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>())), width = ((BaseUnityPlugin)this).Config.Bind<float>(section, "OarWidth", wid, new ConfigDescription("Oar thickness multiplier. Applied when the boat loads.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>())) }; _oarCfg[key] = value; } } internal static float GetYaw(Ship s) { if ((Object)(object)s == (Object)null) { return 0f; } object? value = F_nview.GetValue(s); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { return 0f; } return val.GetZDO().GetFloat("bouns_sailyaw", 0f); } internal static ZNetView NView(Ship s) { if (!((Object)(object)s == (Object)null)) { object? value = F_nview.GetValue(s); return (ZNetView)((value is ZNetView) ? value : null); } return null; } internal static bool SailUp(Ship s) { try { return M_isSailUp != null && (bool)M_isSailUp.Invoke(s, null); } catch { return true; } } internal static Vector3 SailNormal(Ship s, float yaw) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Quaternion.AngleAxis(yaw, Vector3.up) * ((Component)s).transform.forward; } internal static float Efficiency(Ship s, float yaw) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) float num = ((MinEfficiency != null) ? MinEfficiency.Value : 0f); EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null) { return num; } Vector3 windDir = instance.GetWindDir(); Vector3 val = SailNormal(s, yaw); float num2 = Mathf.Max(0f, Vector3.Dot(windDir, val)); return Mathf.Clamp01(Mathf.Max(num, num2)); } private static Ship FindMyShip(Player local) { List<IMonoUpdater> instances = Ship.Instances; if (instances == null) { return null; } for (int i = 0; i < instances.Count; i++) { IMonoUpdater obj = instances[i]; Ship val = (Ship)(object)((obj is Ship) ? obj : null); if ((Object)(object)val != (Object)null && val.IsPlayerInBoat(local)) { return val; } } return null; } internal static string BoatKey(Ship s) { string text = (((Object)(object)s != (Object)null && ((Object)s).name != null) ? ((Object)s).name.ToLowerInvariant() : ""); if (text.Contains("raft")) { return "Raft"; } if (text.Contains("karve")) { return "Karve"; } if (text.Contains("cargo")) { return null; } if (text.Contains("ashlands")) { return "Drakkar"; } if (!text.Contains("vikingship")) { text.Contains("longship"); } return "Longship"; } internal static OarCfg CfgFor(Ship s) { string text = BoatKey(s); if (text == null || !_oarCfg.TryGetValue(text, out var value)) { return null; } return value; } internal static int OarCount(Ship s) { return CfgFor(s)?.count.Value ?? 0; } internal static RowerState Rowers(Ship s) { return _rowers.GetOrCreateValue(s); } internal static int CountAndPurgeRowers(Ship s) { if (!_rowers.TryGetValue(s, out var value) || value.beats.Count == 0) { return 0; } float time = Time.time; _staleBuf.Clear(); foreach (KeyValuePair<long, float> beat in value.beats) { if (time - beat.Value > 1.5f) { _staleBuf.Add(beat.Key); } } for (int i = 0; i < _staleBuf.Count; i++) { value.beats.Remove(_staleBuf[i]); } int num = OarCount(s); int count = value.beats.Count; if (count >= num) { return num; } return count; } internal static int RowerCount(Ship s) { ZNetView val = NView(s); if ((Object)(object)val == (Object)null || !val.IsValid()) { return 0; } return Mathf.RoundToInt(val.GetZDO().GetFloat("bouns_rowers", 0f)); } internal static string SteerAnim(Ship s) { try { object value = F_shipControlls.GetValue(s); string text = ((value != null) ? (F_scAnim.GetValue(value) as string) : null); return string.IsNullOrEmpty(text) ? "attach_chair" : text; } catch { return "attach_chair"; } } internal static Vector3 SteerDetach(Ship s) { //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_0036: 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) try { object value = F_shipControlls.GetValue(s); if (value != null) { return (Vector3)F_scDetach.GetValue(value); } } catch { } return new Vector3(0f, 0.5f, 0f); } internal static float DeckY(Ship s) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) try { object value = F_shipControlls.GetValue(s); Transform val = (Transform)((value != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { return ((Component)s).transform.InverseTransformPoint(val.position).y; } } catch { } return 0.5f; } internal static void ClearStationFlags() { StationRowing = false; StationShip = null; CurrentStation = null; } internal static void LeaveStation() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && localPlayer.GetDoodadController() != null) { localPlayer.StopDoodadControl(); return; } if ((Object)(object)localPlayer != (Object)null && ((Character)localPlayer).IsAttached()) { ((Character)localPlayer).AttachStop(); } ClearStationFlags(); } private void ApplyYaw(Ship ship, float yaw) { ZNetView val = NView(ship); if (!((Object)(object)val == (Object)null) && val.IsValid()) { if (val.IsOwner()) { val.GetZDO().Set("bouns_sailyaw", yaw); } else if (Mathf.Abs(yaw - _lastRpcYaw) > 0.01f && Time.time - _lastRpcTime > 0.1f) { val.InvokeRPC("bouns_setsail", new object[1] { yaw }); _lastRpcYaw = yaw; _lastRpcTime = Time.time; } } } private void SendRow(Ship ship, bool on) { ZNetView val = NView(ship); if (!((Object)(object)val == (Object)null) && val.IsValid()) { val.InvokeRPC("bouns_row", new object[1] { on ? 1 : 0 }); } } private void StopRowing() { if (_wasRowing && (Object)(object)_rowShip != (Object)null) { SendRow(_rowShip, on: false); } if (StationRowing) { LeaveStation(); } _wasRowing = false; _rowShip = null; } private void Update() { if (!Enabled.Value) { _editShip = null; StopRowing(); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _editShip = null; StopRowing(); return; } Ship val = FindMyShip(localPlayer); if ((Object)(object)val == (Object)null) { _editShip = null; StopRowing(); } else { HandleSail(val); HandleRowing(localPlayer); } } private void HandleSail(Ship ship) { //IL_000b: 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) float num = 0f; if (Input.GetKey(KeyLeft.Value)) { num -= 1f; } if (Input.GetKey(KeyRight.Value)) { num += 1f; } if (num == 0f) { _editShip = null; return; } if ((Object)(object)_editShip != (Object)(object)ship) { _editShip = ship; _editYaw = GetYaw(ship); } _editYaw = Mathf.Clamp(_editYaw + num * RotateSpeed.Value * Time.deltaTime, 0f - MaxAngle.Value, MaxAngle.Value); ApplyYaw(ship, _editYaw); } private void HandleRowing(Player local) { if (!OarsEnabled.Value) { if (_wasRowing && (Object)(object)_rowShip != (Object)null) { SendRow(_rowShip, on: false); } if (StationRowing) { LeaveStation(); } _wasRowing = false; return; } if (StationRowing && ((Object)(object)local == (Object)null || !((Character)local).IsAttached())) { ClearStationFlags(); } bool stationRowing = StationRowing; Ship stationShip = StationShip; if (stationRowing && (Object)(object)stationShip != (Object)null) { _rowShip = stationShip; if (Time.time - _lastRowBeat > 0.5f) { SendRow(stationShip, on: true); _lastRowBeat = Time.time; } } else if (_wasRowing && (Object)(object)_rowShip != (Object)null) { SendRow(_rowShip, on: false); } _wasRowing = stationRowing; } private void OnGUI() { if (!Enabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Ship val = FindMyShip(localPlayer); if ((Object)(object)val == (Object)null) { return; } if (OarsEnabled.Value) { int num = RowerCount(val); bool stationRowing = StationRowing; if (num > 0 || stationRowing) { DrawLabel("Oars " + num + "/" + OarCount(val) + (stationRowing ? " (rowing)" : ""), 0.31f); } } if (Debug.Value) { float num2 = (((Object)(object)_editShip == (Object)(object)val) ? _editYaw : GetYaw(val)); int num3 = Mathf.RoundToInt(Efficiency(val, num2) * 100f); DrawLabel("Sail " + Mathf.RoundToInt(num2) + "° Wind " + num3 + "%", 0.275f); } } private static void DrawLabel(string txt, float yFrac) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) GUIStyle val = new GUIStyle { alignment = (TextAnchor)5, fontSize = 18, fontStyle = (FontStyle)1, richText = false }; Font val2 = GameFont(); if ((Object)(object)val2 != (Object)null) { val.font = val2; } Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, (float)Screen.height * yFrac, (float)Screen.width - 30f, 26f); val.normal.textColor = new Color(0f, 0f, 0f, 0.8f); GUI.Label(new Rect(((Rect)(ref val3)).x + 2f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), txt, val); val.normal.textColor = Color.white; GUI.Label(val3, txt, val); } private static Font GameFont() { if (_fontTried) { return _font; } _fontTried = true; try { Font val = null; Font val2 = null; Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val3 in array) { if (!((Object)(object)val3 == (Object)null)) { string text = ((Object)val3).name ?? ""; if ((Object)(object)val == (Object)null && text.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0) { val = val3; } else if ((Object)(object)val2 == (Object)null && text.IndexOf("Averia", StringComparison.OrdinalIgnoreCase) >= 0) { val2 = val3; } } } _font = (((Object)(object)val != (Object)null) ? val : val2); } catch { _font = null; } return _font; } } internal sealed class OarStation : MonoBehaviour, Interactable, Hoverable, IDoodadController { internal Ship ship; internal Plugin.OarCfg cfg; internal Transform stand; internal Transform oarPivot; internal float sideSign; internal int slot; internal int perSide; private float _lastSide = float.NaN; private float _lastHeight; private float _lastSpacing; private float _lastStand; private float _deckY; private bool _deckYCached; private bool _wasActive; private void Update() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) if (cfg == null) { return; } float value = cfg.side.Value; float value2 = cfg.height.Value; float value3 = cfg.spacing.Value; float value4 = cfg.stand.Value; if (value != _lastSide || value2 != _lastHeight || value3 != _lastSpacing || value4 != _lastStand) { _lastSide = value; _lastHeight = value2; _lastSpacing = value3; _lastStand = value4; float num = value * sideSign; float num2 = ((float)slot - (float)(perSide - 1) * 0.5f) * value3; ((Component)this).transform.localPosition = new Vector3(num, value2, num2); if ((Object)(object)stand != (Object)null) { if (!_deckYCached) { _deckY = Plugin.DeckY(ship); _deckYCached = true; } stand.localPosition = new Vector3(num, _deckY + value4, num2); } } if ((Object)(object)oarPivot != (Object)null) { bool flag = Plugin.StationRowing && (Object)(object)Plugin.CurrentStation == (Object)(object)this; if (flag) { oarPivot.localRotation = Quaternion.Euler(0f, Mathf.Sin(Time.time * 3f) * 22f, 0f); } else if (_wasActive) { oarPivot.localRotation = Quaternion.identity; } _wasActive = flag; } } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return false; } if (Plugin.StationRowing) { Plugin.LeaveStation(); } else { Man(val); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { string text = (Plugin.StationRowing ? "[<color=yellow><b>$KEY_Use</b></color>] Leave oar" : "[<color=yellow><b>$KEY_Use</b></color>] Man oar"); try { return Localization.instance.Localize(text); } catch { return text; } } public string GetHoverName() { return "Oar"; } public float GetHoverOffset() { return 0f; } private void Man(Player p) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ship == (Object)null)) { p.StartDoodadControl((IDoodadController)(object)this); Transform val = (((Object)(object)stand != (Object)null) ? stand : ((Component)this).transform); ((Character)p).AttachStart(val, (GameObject)null, false, false, true, Plugin.SteerAnim(ship), Plugin.SteerDetach(ship), (Transform)null); Plugin.StationRowing = true; Plugin.StationShip = ship; Plugin.CurrentStation = this; } } public void ApplyControlls(Vector3 moveDir, Vector3 lookDir, bool run, bool autoRun, bool block) { } public Component GetControlledComponent() { return (Component)(object)this; } public Vector3 GetPosition() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ((Component)this).transform.position; } public bool IsValid() { return (Object)(object)ship != (Object)null; } public void OnUseStop(Player player) { if ((Object)(object)player != (Object)null && ((Character)player).IsAttached()) { ((Character)player).AttachStop(); } Plugin.ClearStationFlags(); } } [HarmonyPatch(typeof(Ship), "GetWindAngleFactor")] internal static class Patch_GetWindAngleFactor { private static bool Prefix(Ship __instance, ref float __result) { if (!Plugin.Enabled.Value) { return true; } __result = Plugin.Efficiency(__instance, Plugin.GetYaw(__instance)); return false; } } [HarmonyPatch(typeof(Ship), "UpdateSail")] internal static class Patch_UpdateSail { private static readonly FieldInfo F_mast = AccessTools.Field(typeof(Ship), "m_mastObject"); private static void Postfix(Ship __instance) { //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_0051: 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_0057: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.SailUp(__instance)) { return; } object? value = F_mast.GetValue(__instance); GameObject val = (GameObject)((value is GameObject) ? value : null); if (!((Object)(object)val == (Object)null)) { Vector3 val2 = Plugin.SailNormal(__instance, Plugin.GetYaw(__instance)); if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { val.transform.rotation = Quaternion.LookRotation(val2, Vector3.up); } } } } [HarmonyPatch(typeof(Ship), "CustomFixedUpdate")] internal static class Patch_Ship_Rowing { private static readonly FieldInfo F_body = AccessTools.Field(typeof(Ship), "m_body"); private static readonly MethodInfo M_haveCtrl = AccessTools.Method(typeof(Ship), "HaveControllingPlayer", (Type[])null, (Type[])null); private static bool HasPilot(Ship s) { try { return M_haveCtrl != null && (bool)M_haveCtrl.Invoke(s, null); } catch { return true; } } private static void Postfix(Ship __instance) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.OarsEnabled.Value) { return; } ZNetView val = Plugin.NView(__instance); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } int num = Plugin.CountAndPurgeRowers(__instance); val.GetZDO().Set("bouns_rowers", (float)num); if (num <= 0 || !HasPilot(__instance)) { return; } object? value = F_body.GetValue(__instance); Rigidbody val2 = (Rigidbody)((value is Rigidbody) ? value : null); if (!((Object)(object)val2 == (Object)null)) { Speed speedSetting = __instance.GetSpeedSetting(); if ((int)speedSetting != 0) { float num2 = (((int)speedSetting == 1) ? (-1f) : 1f); float num3 = (Plugin.SailUp(__instance) ? Plugin.BonusUp.Value : Plugin.BonusDown.Value); float num4 = (float)num * (num3 / 100f) * 9.8f; val2.AddForce(((Component)__instance).transform.forward * (num2 * num4 * val2.mass), (ForceMode)0); } } } } [HarmonyPatch(typeof(Ship), "Awake")] internal static class Patch_Ship_Awake_Setup { private static readonly FieldInfo F_nview = AccessTools.Field(typeof(Ship), "m_nview"); private static Mesh _cubeMesh; private static void Postfix(Ship __instance) { ZNetView nv = default(ZNetView); ref ZNetView reference = ref nv; object? value = F_nview.GetValue(__instance); reference = (ZNetView)((value is ZNetView) ? value : null); if ((Object)(object)nv != (Object)null) { nv.Register<float>("bouns_setsail", (Action<long, float>)delegate(long sender, float yaw) { if (nv.IsValid() && nv.IsOwner()) { nv.GetZDO().Set("bouns_sailyaw", yaw); } }); nv.Register<int>("bouns_row", (Action<long, int>)delegate(long sender, int on) { if (nv.IsValid() && nv.IsOwner()) { Plugin.RowerState rowerState = Plugin.Rowers(__instance); if (on != 0) { rowerState.beats[sender] = Time.time; } else { rowerState.beats.Remove(sender); } } }); } SpawnOarStations(__instance); } private static void SpawnOarStations(Ship ship) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.OarsEnabled.Value) { return; } Plugin.OarCfg oarCfg = Plugin.CfgFor(ship); if (oarCfg == null) { return; } int value = oarCfg.count.Value; if (value <= 0) { return; } int num = LayerMask.NameToLayer("piece"); Material val = PickHullMaterial(ship); int num2 = (value + 1) / 2; int num3 = 0; for (int i = 0; i < 2; i++) { if (num3 >= value) { break; } float num4 = ((i == 0) ? (-1f) : 1f); for (int j = 0; j < num2; j++) { if (num3 >= value) { break; } GameObject val2 = new GameObject("bouns_oar"); val2.transform.SetParent(((Component)ship).transform, false); if (num >= 0) { val2.layer = num; } BoxCollider obj = val2.AddComponent<BoxCollider>(); obj.size = new Vector3(0.8f, 1.2f, 0.8f); ((Collider)obj).isTrigger = true; Transform transform = new GameObject("bouns_oar_stand").transform; transform.SetParent(((Component)ship).transform, false); OarStation oarStation = val2.AddComponent<OarStation>(); oarStation.ship = ship; oarStation.cfg = oarCfg; oarStation.stand = transform; oarStation.sideSign = num4; oarStation.slot = j; oarStation.perSide = num2; oarStation.oarPivot = BuildOar(val2.transform, num4, val, oarCfg.length.Value, oarCfg.width.Value); num3++; } } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)string.Format("[Oars] {0}: placed {1} oar stations (layer 'piece'={2}, mat={3}).", ((Object)ship).name, num3, num, ((Object)(object)val != (Object)null) ? ((Object)val).name : "none")); } } private static Material PickHullMaterial(Ship ship) { Material val = null; MeshRenderer[] componentsInChildren = ((Component)ship).GetComponentsInChildren<MeshRenderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { Material sharedMaterial = ((Renderer)componentsInChildren[i]).sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null)) { if ((Object)(object)val == (Object)null) { val = sharedMaterial; } string text = ((Object)sharedMaterial).name.ToLowerInvariant(); if (!text.Contains("water") && !text.Contains("mask") && !text.Contains("sail") && !text.Contains("cloth") && !text.Contains("flag") && !text.Contains("rope") && !text.Contains("smoke") && !text.Contains("fx") && !text.Contains("particle") && !text.Contains("foam") && !text.Contains("cloud")) { return sharedMaterial; } } } return val; } private static Transform BuildOar(Transform parent, float sign, Material mat, float lm, float wm) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) Transform transform = new GameObject("bouns_oar_pivot").transform; transform.SetParent(parent, false); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(sign * 0.77f, -0.64f, 0f); Quaternion rot = Quaternion.FromToRotation(Vector3.right, val); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(sign * 0.15f, 0.2f, 0f); float num = 1.9f * lm; float num2 = 0.06f * wm; OarPart(transform, mat, val2 + val * (num * 0.5f), rot, new Vector3(num, num2, num2)); float num3 = 0.55f * wm; OarPart(transform, mat, val2 + val * (num + num3 * 0.4f), rot, new Vector3(num3, 0.05f * wm, 0.26f * wm)); return transform; } private static Mesh CubeMesh() { if ((Object)(object)_cubeMesh == (Object)null) { GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); _cubeMesh = obj.GetComponent<MeshFilter>().sharedMesh; Object.Destroy((Object)(object)obj); } return _cubeMesh; } private static void OarPart(Transform parent, Material mat, Vector3 pos, Quaternion rot, Vector3 scale) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) GameObject val = new GameObject("bouns_oar_part"); val.transform.SetParent(parent, false); val.transform.localPosition = pos; val.transform.localRotation = rot; val.transform.localScale = scale; val.AddComponent<MeshFilter>().sharedMesh = CubeMesh(); MeshRenderer val2 = val.AddComponent<MeshRenderer>(); if ((Object)(object)mat != (Object)null) { ((Renderer)val2).sharedMaterial = mat; } ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; } } }