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 VikingOarsmen v3.4.0
VikingOarsmen.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Audio; using UnityEngine.Playables; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("VikingOarsmen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.4.0.0")] [assembly: AssemblyInformationalVersion("3.4.0+ba7e82957bb61b594d446ab35d60c6216da9b1db")] [assembly: AssemblyProduct("VikingOarsmen")] [assembly: AssemblyTitle("VikingOarsmen")] [assembly: AssemblyVersion("3.4.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 VikingOarsmen { internal class CrewHud : MonoBehaviour { private class Marker { public RectTransform Oar; public RectTransform Ring; public Image Token; public RectTransform Helmet; } private static readonly Vector2 s_panelSize = new Vector2(180f, 340f); private const float PanelX = 110f; private static readonly Vector2 s_shipArea = new Vector2(138f, 232f); private const float ShipAreaY = -21f; private const float EndLabelOffset = 124f; private const float FlipMargin = 0.2f; private const float IconSize = 18f; private const float CountFontSize = 22f; private const float CaptionFontSize = 10f; private static readonly Color s_countColor = Color32.op_Implicit(new Color32((byte)58, (byte)34, (byte)14, byte.MaxValue)); private static readonly Color s_captionColor = Color32.op_Implicit(new Color32((byte)92, (byte)58, (byte)28, byte.MaxValue)); private const float MaxToken = 16f; private const float MinToken = 11f; private const float TokenPerMeter = 1.6f; private static readonly Vector2 s_oarSize = new Vector2(32f, 6f); private const float RingScale = 1.5f; private const float SwingDegrees = 30f; private static readonly Color s_passengerColor = new Color(0.55f, 0.55f, 0.55f); private readonly List<Player> _aboard = new List<Player>(); private readonly List<Marker> _markers = new List<Marker>(); private Hud _hud; private RectTransform _root; private RectTransform _view; private Image _ship; private RectTransform _crew; private TextMeshProUGUI _topLabel; private TextMeshProUGUI _bottomLabel; private bool _sternUp; private TextMeshProUGUI _rowingCount; private TextMeshProUGUI _aboardCount; private int _shownRowers = -1; private int _shownAboard = -1; private void Start() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) _hud = ((Component)this).GetComponent<Hud>(); if ((Object)(object)CrewHudArt.Get("frame") == (Object)null) { Plugin.Log.LogWarning((object)"Crew panel artwork couldn't be loaded; the crew panel is disabled."); return; } Transform parent = (((Object)(object)_hud.m_rootObject != (Object)null) ? _hud.m_rootObject.transform : ((Component)this).transform); _root = NewRect("VikingOarsmen_CrewHud", parent); RectTransform root = _root; RectTransform root2 = _root; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 0.5f); root2.anchorMax = val; root.anchorMin = val; _root.sizeDelta = s_panelSize; _root.anchoredPosition = new Vector2(110f, 0f); Image obj = NewImage("Frame", (Transform)(object)_root, "frame"); ((Graphic)obj).rectTransform.anchorMin = Vector2.zero; ((Graphic)obj).rectTransform.anchorMax = Vector2.one; ((Graphic)obj).rectTransform.sizeDelta = Vector2.zero; _rowingCount = BuildCounter(24f, "icon_oar", "ROWING"); _aboardCount = BuildCounter(102f, "icon_crew", "ABOARD"); _view = NewRect("View", (Transform)(object)_root); _view.anchoredPosition = new Vector2(0f, -21f); _ship = NewImage("Ship", (Transform)(object)_view, null); _crew = NewRect("Crew", (Transform)(object)_view); _topLabel = NewEndLabel("Top", 124f); _bottomLabel = NewEndLabel("Bottom", -124f); ApplyOrientation(); ((Component)_root).gameObject.SetActive(false); } private void LateUpdate() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: 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) if ((Object)(object)_root == (Object)null) { return; } if (!Plugin.ShowCrewHud.Value || !TryCollectAboard(out var ship, out var shipId)) { ((Component)_root).gameObject.SetActive(false); return; } CrewHudArt.ShipArt shipArt = CrewHudArt.For(ship); float num = shipArt.ZMax - shipArt.ZMin; float num2 = Mathf.Min(s_shipArea.y / num, s_shipArea.x / (shipArt.HalfWidth * 2f)); float num3 = (shipArt.ZMin + shipArt.ZMax) / 2f; _ship.sprite = CrewHudArt.Get(shipArt.Sprite); ((Graphic)_ship).rectTransform.sizeDelta = new Vector2(shipArt.HalfWidth * 2f * num2, num * num2); UpdateOrientation(ship); ((Component)_root).gameObject.SetActive(true); float num4 = Mathf.Clamp(num2 * 1.6f, 11f, 16f); AnimationClip stroke = ModAssets.RowStroke(mirrored: false); int num5 = 0; Vector2 anchoredPosition = default(Vector2); for (int i = 0; i < _aboard.Count; i++) { Player val = _aboard[i]; Marker marker = GetMarker(i); Transform attachPoint = val.GetAttachPoint(); Vector3 val2 = ((Component)ship).transform.InverseTransformPoint(((Object)(object)attachPoint != (Object)null) ? attachPoint.position : ((Component)val).transform.position); ((Vector2)(ref anchoredPosition))..ctor(val2.x * num2, (val2.z - num3) * num2); bool flag = RowingController.GetRowingShip(val) == shipId; RowingGear gear = (flag ? RowingController.GetRowingGear(val) : RowingGear.Stop); if (flag) { num5++; } ((Component)marker.Ring).gameObject.SetActive((Object)(object)val == (Object)(object)Player.m_localPlayer); marker.Ring.anchoredPosition = anchoredPosition; marker.Ring.sizeDelta = Vector2.one * num4 * 1.5f; ((Graphic)marker.Token).rectTransform.anchoredPosition = anchoredPosition; ((Graphic)marker.Token).rectTransform.sizeDelta = Vector2.one * num4; ((Graphic)marker.Token).color = (flag ? GearColor(gear) : s_passengerColor); marker.Helmet.anchoredPosition = anchoredPosition; marker.Helmet.sizeDelta = Vector2.one * num4; ((Component)marker.Oar).gameObject.SetActive(flag); marker.Oar.anchoredPosition = anchoredPosition; marker.Oar.sizeDelta = s_oarSize * (num4 / 16f); ((Transform)marker.Oar).localRotation = Quaternion.Euler(0f, 0f, OarAngle(gear, (val2.x < 0f) ? (-1f) : 1f, stroke)); } for (int j = _aboard.Count; j < _markers.Count; j++) { HideMarker(_markers[j]); } if (num5 != _shownRowers || _aboard.Count != _shownAboard) { _shownRowers = num5; _shownAboard = _aboard.Count; ((TMP_Text)_rowingCount).text = num5.ToString(); ((TMP_Text)_aboardCount).text = _aboard.Count.ToString(); } } private void OnDestroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } } private bool TryCollectAboard(out Ship ship, out ZDOID shipId) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) _aboard.Clear(); ship = null; shipId = ZDOID.None; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !RowingController.IsRowingMode(localPlayer)) { return false; } shipId = RowingController.GetRowingShip(localPlayer); ship = ((Component)localPlayer).GetComponent<OarVisual>()?.RowingShip; if (shipId == ZDOID.None || (Object)(object)ship == (Object)null) { return false; } foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null && (ship.IsPlayerInBoat(allPlayer) || RowingController.GetRowingShip(allPlayer) == shipId)) { _aboard.Add(allPlayer); } } return true; } private void UpdateOrientation(Ship ship) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera == (Object)null) { return; } Vector3 val = Vector3.ProjectOnPlane(((Component)mainCamera).transform.forward, ((Component)ship).transform.up); if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f)) { float num = Vector3.Dot(((Vector3)(ref val)).normalized, ((Component)ship).transform.forward); bool flag = num < -0.2f || (_sternUp && num < 0.2f); if (flag != _sternUp) { _sternUp = flag; ApplyOrientation(); } } } private void ApplyOrientation() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ((Transform)_view).localRotation = Quaternion.Euler(0f, 0f, _sternUp ? 180f : 0f); ((TMP_Text)_topLabel).text = (_sternUp ? "STERN" : "BOW"); ((TMP_Text)_bottomLabel).text = (_sternUp ? "BOW" : "STERN"); } private TextMeshProUGUI NewEndLabel(string name, float y) { //IL_0007: 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_003d: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = NewText(name, 10f, s_captionColor); ((TMP_Text)obj).rectTransform.anchoredPosition = new Vector2(0f, -21f + y); ((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(80f, 14f); ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).characterSpacing = 4f; return obj; } private static float OarAngle(RowingGear gear, float side, AnimationClip stroke) { float num = ((side > 0f) ? 0f : 180f); float num2 = (((Object)(object)stroke != (Object)null) ? RowingBeat.StrokeRate(gear, stroke.length) : 0f); if (num2 <= 0f) { return num; } float num3 = Mathf.Sin(RowingBeat.GetBeat(num2) * (float)Math.PI * 2f) * 30f; if (gear == RowingGear.Back) { num3 = 0f - num3; } return num + num3 * side; } private static Color GearColor(RowingGear gear) { //IL_0029: 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_0053: 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_007d: Unknown result type (might be due to invalid IL or missing references) return (Color)(gear switch { RowingGear.Back => new Color(1f, 0.55f, 0.15f), RowingGear.Slow => new Color(0.45f, 0.85f, 0.4f), RowingGear.Half => new Color(1f, 0.9f, 0.3f), RowingGear.Full => new Color(0.95f, 0.3f, 0.25f), _ => new Color(0.7f, 0.7f, 0.7f), }); } private TextMeshProUGUI BuildCounter(float x, string icon, string caption) { //IL_0022: 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_0063: 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_0098: Unknown result type (might be due to invalid IL or missing references) PlaceTopLeft(((Graphic)NewImage(icon, (Transform)(object)_root, icon)).rectTransform, x, 13f, new Vector2(18f, 18f)); TextMeshProUGUI obj = NewText("Count", 22f, s_countColor); PlaceTopLeft(((TMP_Text)obj).rectTransform, x + 18f + 4f, 9f, new Vector2(40f, 26f)); TextMeshProUGUI obj2 = NewText("Caption", 10f, s_captionColor); PlaceTopLeft(((TMP_Text)obj2).rectTransform, x, 32f, new Vector2(70f, 14f)); ((TMP_Text)obj2).text = caption; ((TMP_Text)obj2).characterSpacing = 4f; return obj; } private TextMeshProUGUI NewText(string name, float size, Color color) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((Component)NewRect(name, (Transform)(object)_root)).gameObject.AddComponent<TextMeshProUGUI>(); if ((Object)(object)_hud.m_hoverName != (Object)null) { ((TMP_Text)val).font = ((TMP_Text)_hud.m_hoverName).font; } ((TMP_Text)val).fontSize = size; ((TMP_Text)val).fontStyle = (FontStyles)1; ((Graphic)val).color = color; ((TMP_Text)val).alignment = (TextAlignmentOptions)513; ((TMP_Text)val).textWrappingMode = (TextWrappingModes)0; ((Graphic)val).raycastTarget = false; return val; } private Marker GetMarker(int index) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) while (_markers.Count <= index) { Marker marker = new Marker(); marker.Oar = ((Graphic)NewImage("Oar", (Transform)(object)_crew, "oar")).rectTransform; marker.Oar.pivot = new Vector2(0f, 0.5f); marker.Ring = ((Graphic)NewImage("Self", (Transform)(object)_crew, "self_ring")).rectTransform; marker.Token = NewImage("Player", (Transform)(object)_crew, "token"); marker.Helmet = ((Graphic)NewImage("Helmet", (Transform)(object)_crew, "helmet")).rectTransform; _markers.Add(marker); } Marker marker2 = _markers[index]; ((Component)marker2.Token).gameObject.SetActive(true); ((Component)marker2.Helmet).gameObject.SetActive(true); return marker2; } private static void HideMarker(Marker marker) { ((Component)marker.Oar).gameObject.SetActive(false); ((Component)marker.Ring).gameObject.SetActive(false); ((Component)marker.Token).gameObject.SetActive(false); ((Component)marker.Helmet).gameObject.SetActive(false); } private static void PlaceTopLeft(RectTransform rect, float x, float y, Vector2 size) { //IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(x, 0f - y); rect.sizeDelta = size; } private static Image NewImage(string name, Transform parent, string sprite) { Image val = ((Component)NewRect(name, parent)).gameObject.AddComponent<Image>(); if (sprite != null) { val.sprite = CrewHudArt.Get(sprite); } ((Graphic)val).raycastTarget = false; return val; } private static RectTransform NewRect(string name, Transform parent) { //IL_0014: 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_003f: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); component.anchorMax = val; component.anchorMin = val; return component; } } internal static class CrewHudArt { internal class ShipArt { internal readonly string Sprite; internal readonly float HalfWidth; internal readonly float ZMin; internal readonly float ZMax; internal ShipArt(string sprite, float halfWidth, float zMin, float zMax) { Sprite = sprite; HalfWidth = halfWidth; ZMin = zMin; ZMax = zMax; } } private const string ResourcePrefix = "VikingOarsmen.Textures."; private const string FallbackShip = "ship_longship"; private static readonly Dictionary<string, ShipArt> s_ships = new Dictionary<string, ShipArt> { { "Raft", new ShipArt("ship_raft", 3.6f, -3.6f, 3.6f) }, { "Karve", new ShipArt("ship_karve", 1.95f, -6.27f, 6.34f) }, { "VikingShip", new ShipArt("ship_longship", 3.35f, -12.2f, 12.2f) }, { "Trailership", new ShipArt("ship_longship", 3.35f, -12.2f, 12.2f) }, { "VikingShip_Ashlands", new ShipArt("ship_drakkar", 6.6f, -18.8f, 19.8f) } }; private static readonly Dictionary<string, Sprite> s_sprites = new Dictionary<string, Sprite>(); private static readonly MethodInfo s_loadImage = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); internal static ShipArt For(Ship ship) { //IL_0041: 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_0067: 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_008e: Unknown result type (might be due to invalid IL or missing references) if (s_ships.TryGetValue(Utils.GetPrefabName(((Component)ship).gameObject), out var value)) { return value; } BoxCollider floatCollider = ship.m_floatCollider; if ((Object)(object)floatCollider == (Object)null) { return s_ships["VikingShip"]; } return new ShipArt("ship_longship", Mathf.Max(floatCollider.size.x, 0.5f) / 2f, floatCollider.center.z - Mathf.Max(floatCollider.size.z, 0.5f) / 2f, floatCollider.center.z + Mathf.Max(floatCollider.size.z, 0.5f) / 2f); } internal static Sprite Get(string name) { if (s_sprites.TryGetValue(name, out var value)) { return value; } value = Load(name); s_sprites[name] = value; return value; } private static Sprite Load(string name) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) using Stream stream = typeof(CrewHudArt).Assembly.GetManifestResourceStream("VikingOarsmen.Textures." + name + ".png"); if (stream == null) { Plugin.Log.LogError((object)("Embedded texture '" + name + ".png' not found in the DLL.")); return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (s_loadImage == null) { Plugin.Log.LogError((object)"UnityEngine.ImageConversion.LoadImage not found; the crew panel's textures can't be decoded."); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!(bool)s_loadImage.Invoke(null, new object[2] { val, array })) { Plugin.Log.LogError((object)("Embedded texture '" + name + ".png' couldn't be decoded.")); Object.Destroy((Object)(object)val); return null; } ((Object)val).name = "VikingOarsmen_" + name; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } internal class GearHud : MonoBehaviour { private const float HeightAboveGunwale = 0.3f; private Hud _hud; private GameObject _root; private Transform _controlsRoot; private GameObject _slow; private GameObject _half; private GameObject _full; private GameObject _back; private void Start() { _hud = ((Component)this).GetComponent<Hud>(); if (!Build()) { Plugin.Log.LogWarning((object)"Ship HUD layout not recognized; the gear indicator is disabled."); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } } } private bool Build() { GameObject shipHudRoot = _hud.m_shipHudRoot; if ((Object)(object)shipHudRoot == (Object)null) { return false; } _root = Object.Instantiate<GameObject>(shipHudRoot, shipHudRoot.transform.parent); ((Object)_root).name = "VikingOarsmen_GearHud"; _root.SetActive(false); _controlsRoot = FindCounterpart(_hud.m_shipControlsRoot); _slow = FindCounterpartObject(_hud.m_rudderSlow); _half = FindCounterpartObject(_hud.m_rudderForward); _full = FindCounterpartObject(_hud.m_rudderFastForward); _back = FindCounterpartObject(_hud.m_rudderBackward); if ((Object)(object)_controlsRoot == (Object)null || (Object)(object)_slow == (Object)null || (Object)(object)_half == (Object)null || (Object)(object)_full == (Object)null || (Object)(object)_back == (Object)null || (Object)(object)FindCounterpart((Component)(object)_hud.m_shipRudderIcon) == (Object)null) { return false; } Hide(_hud.m_rudderLeft); Hide(_hud.m_rudderRight); Hide(_hud.m_halfSail); Hide(_hud.m_fullSail); Hide(_hud.m_rudder); Hide((Component)(object)_hud.m_shipWindIndicatorRoot); Hide((Component)(object)_hud.m_shipRudderIndicator); return true; } private void LateUpdate() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !RowingController.IsRowingMode(localPlayer)) { _root.SetActive(false); return; } Camera mainCamera = Utils.GetMainCamera(); OarVisual component = ((Component)localPlayer).GetComponent<OarVisual>(); if ((Object)(object)mainCamera == (Object)null || (Object)(object)component == (Object)null || !component.TryGetGunwalePoint(out var point)) { _root.SetActive(false); return; } RowingGear selectedGear = RowingController.GetSelectedGear(); _root.SetActive(true); _slow.SetActive(selectedGear == RowingGear.Slow); _half.SetActive(selectedGear == RowingGear.Half); _full.SetActive(selectedGear == RowingGear.Full); _back.SetActive(selectedGear == RowingGear.Back); _controlsRoot.position = Utils.WorldToScreenPointScaled(mainCamera, point + Vector3.up * 0.3f); } private void OnDestroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } private Transform FindCounterpart(Component original) { if (!((Object)(object)original != (Object)null)) { return null; } return FindCounterpart(original.gameObject); } private Transform FindCounterpart(GameObject original) { if ((Object)(object)original == (Object)null) { return null; } Transform transform = _hud.m_shipHudRoot.transform; Transform transform2 = original.transform; if ((Object)(object)transform2 == (Object)(object)transform) { return _root.transform; } string text = ((Object)transform2).name; transform2 = transform2.parent; while ((Object)(object)transform2 != (Object)null && (Object)(object)transform2 != (Object)(object)transform) { text = ((Object)transform2).name + "/" + text; transform2 = transform2.parent; } if (!((Object)(object)transform2 == (Object)(object)transform)) { return null; } return _root.transform.Find(text); } private GameObject FindCounterpartObject(GameObject original) { Transform val = FindCounterpart(original); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).gameObject; } private void Hide(Component original) { if ((Object)(object)original != (Object)null) { Hide(original.gameObject); } } private void Hide(GameObject original) { Transform val = FindCounterpart(original); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } } } internal static class ModAssets { private const string BundleName = "vikingoarsmen"; private const string RowIdleName = "row_idle"; private const string RowStrokeName = "row_stroke"; private const string MirrorSuffix = "_mirror"; private static bool s_loaded; private static AssetBundle s_bundle; private static AnimationClip s_rowIdle; private static AnimationClip s_rowStroke; private static AnimationClip s_rowIdleMirror; private static AnimationClip s_rowStrokeMirror; internal static GameObject LoadPrefab(string name) { Load(); if (!((Object)(object)s_bundle != (Object)null)) { return null; } return s_bundle.LoadAsset<GameObject>(name); } internal static Sprite LoadSprite(string name) { Load(); if (!((Object)(object)s_bundle != (Object)null)) { return null; } return s_bundle.LoadAsset<Sprite>(name); } internal static AnimationClip RowIdle(bool mirrored) { Load(); if (!mirrored) { return s_rowIdle; } return s_rowIdleMirror; } internal static AnimationClip RowStroke(bool mirrored) { Load(); if (!mirrored) { return s_rowStroke; } return s_rowStrokeMirror; } private static void Load() { if (s_loaded) { return; } s_loaded = true; Assembly assembly = typeof(ModAssets).Assembly; string text = assembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith("vikingoarsmen")); if (text == null) { Plugin.Log.LogError((object)"Embedded AssetBundle 'vikingoarsmen' not found in the DLL."); return; } byte[] array; using (Stream stream = assembly.GetManifestResourceStream(text)) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } AssetBundle val = AssetBundle.LoadFromMemory(array); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Failed to load the AssetBundle 'vikingoarsmen' (built for another platform or Unity version?)."); return; } s_bundle = val; s_rowIdle = val.LoadAsset<AnimationClip>("row_idle"); s_rowStroke = val.LoadAsset<AnimationClip>("row_stroke"); s_rowIdleMirror = val.LoadAsset<AnimationClip>("row_idle_mirror"); s_rowStrokeMirror = val.LoadAsset<AnimationClip>("row_stroke_mirror"); if ((Object)(object)s_rowIdle == (Object)null || (Object)(object)s_rowStroke == (Object)null || (Object)(object)s_rowIdleMirror == (Object)null || (Object)(object)s_rowStrokeMirror == (Object)null) { Plugin.Log.LogWarning((object)"Rowing animations missing from the AssetBundle; rowers will just sit."); } } } internal static class ModSounds { private const string ResourcePrefix = "VikingOarsmen.Sounds."; private static AudioClip[] s_single; private static AudioClip[] s_multiple; private static AudioMixerGroup s_sfxGroup; private static bool s_sfxGroupResolved; internal static AudioClip[] Single { get { if (s_single == null) { s_single = LoadAll("single", "single2"); } return s_single; } } internal static AudioClip[] Multiple { get { if (s_multiple == null) { s_multiple = LoadAll("multiple", "multiple2"); } return s_multiple; } } internal static AudioMixerGroup SfxGroup { get { if (!s_sfxGroupResolved) { ResolveSfxGroup(); } return s_sfxGroup; } } private static void ResolveSfxGroup() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || (Object)(object)AudioMan.instance == (Object)null) { return; } s_sfxGroupResolved = true; foreach (GameObject prefab in instance.m_prefabs) { if (!((Object)(object)prefab == (Object)null) && ((Object)prefab).name.StartsWith("sfx_")) { AudioSource componentInChildren = prefab.GetComponentInChildren<AudioSource>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.outputAudioMixerGroup != (Object)null) { s_sfxGroup = componentInChildren.outputAudioMixerGroup; Plugin.Log.LogInfo((object)("Rowing sound plays through mixer group '" + ((Object)s_sfxGroup).name + "' (from " + ((Object)prefab).name + ").")); return; } } } AudioMixer masterMixer = AudioMan.instance.m_masterMixer; AudioMixerGroup[] array = (((Object)(object)masterMixer != (Object)null) ? masterMixer.FindMatchingGroups("SFX") : null); if (array != null && array.Length != 0) { s_sfxGroup = array[0]; Plugin.Log.LogWarning((object)("No vanilla sound effect to copy the mixer group from; using '" + ((Object)s_sfxGroup).name + "'.")); } else { Plugin.Log.LogWarning((object)"Game's sound effects mixer group not found; the rowing sound ignores the effects volume."); } } private static AudioClip[] LoadAll(params string[] names) { return (from clip in names.Select(Load) where (Object)(object)clip != (Object)null select clip).ToArray(); } private static AudioClip Load(string name) { using Stream stream = typeof(ModSounds).Assembly.GetManifestResourceStream("VikingOarsmen.Sounds." + name + ".wav"); if (stream == null) { Plugin.Log.LogError((object)("Embedded sound '" + name + ".wav' not found in the DLL.")); return null; } using BinaryReader reader = new BinaryReader(stream); return Decode(name, reader); } private static AudioClip Decode(string name, BinaryReader reader) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown //IL_0195: Expected O, but got Unknown if (ReadId(reader) != "RIFF") { return Reject(name, "not a RIFF file"); } reader.ReadInt32(); if (ReadId(reader) != "WAVE") { return Reject(name, "not a WAVE file"); } int num = 0; bool flag = false; while (reader.BaseStream.Position + 8 <= reader.BaseStream.Length) { string text = ReadId(reader); int num2 = reader.ReadInt32(); long position = reader.BaseStream.Position + num2 + (num2 & 1); if (text == "fmt ") { short num3 = reader.ReadInt16(); short num4 = reader.ReadInt16(); num = reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt16(); short num5 = reader.ReadInt16(); flag = num3 == 1 && num4 == 1 && num5 == 16; if (!flag) { return Reject(name, $"format {num3}, {num4} channels, {num5} bit; expected 16-bit mono PCM"); } } else if (text == "data") { if (!flag) { return Reject(name, "data before fmt chunk"); } int count = num2 / 2; float[] samples = new float[count]; for (int i = 0; i < count; i++) { samples[i] = (float)reader.ReadInt16() / 32768f; } int position2 = 0; return AudioClip.Create("VikingOarsmen_" + name, count, 1, num, false, (PCMReaderCallback)delegate(float[] data) { int num6 = Mathf.Clamp(count - position2, 0, data.Length); Array.Copy(samples, position2, data, 0, num6); Array.Clear(data, num6, data.Length - num6); position2 += num6; }, (PCMSetPositionCallback)delegate(int newPosition) { position2 = newPosition; }); } reader.BaseStream.Position = position; } return Reject(name, "no data chunk"); } private static string ReadId(BinaryReader reader) { return Encoding.ASCII.GetString(reader.ReadBytes(4)); } private static AudioClip Reject(string name, string reason) { Plugin.Log.LogWarning((object)("Embedded sound '" + name + ".wav' can't be read (" + reason + "); it won't play.")); return null; } } internal static class OarItem { private class OarKind { internal string PrefabName; internal string ModelPrefab; internal string Icon; internal string Name; internal string Description; internal int StationLevel; internal RequirementConfig[] Requirements; internal Vector3 BackPosition; internal Quaternion BackRotation = Quaternion.identity; internal float Weight = 4f; internal float Durability = 50f; internal float Knockback = 50f; internal float AttackStamina = 12f; internal float AttackRange; internal float Blunt; internal float BluntMaxQuality; internal float BladeTipZ = 2.8f; } private static readonly Vector3 s_backPosition = new Vector3(0f, 0f, -0.8708f); private static readonly Vector3 s_drakkarBackPosition = new Vector3(0.0883f, 1.2553f, -2.2153f); private static readonly Quaternion s_drakkarBackRotation = new Quaternion(0.091977f, 0.220199f, -0.921992f, 0.304931f); private static readonly OarKind s_oar = new OarKind { PrefabName = "VikingOarsmen_Oar", ModelPrefab = "VikingOarsmen_Oar", Icon = "oar_icon", Name = "Oar", Description = "A viking oar. Equip it and sit on a ship's bench to row.", StationLevel = 1, Requirements = (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig("FineWood", 6, 0, true) }, BackPosition = s_backPosition }; private static readonly OarKind s_drakkarOar = new OarKind { PrefabName = "VikingOarsmen_DrakkarOar", ModelPrefab = "VikingOarsmen_DrakkarOar", Icon = "drakkar_oar_icon", Name = "Drakkar Oar", Description = "A long oar for the Drakkar's high benches, the only one that reaches the water from them. Equip it and sit on a ship's bench to row.", StationLevel = 2, Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("YggdrasilWood", 16, 0, true), new RequirementConfig("Resin", 8, 0, true) }, BackPosition = s_drakkarBackPosition, BackRotation = s_drakkarBackRotation, Weight = 8f, Durability = 90f, Knockback = 300f, AttackStamina = 15f, AttackRange = 6f, Blunt = 70f, BluntMaxQuality = 90f }; private static readonly OarKind[] s_kinds = new OarKind[2] { s_oar, s_drakkarOar }; private const float Weight = 4f; private const float Durability = 50f; private const float Knockback = 50f; private const float BackstabBonus = 2f; private const float StaggerMultiplier = 1.5f; private const float AttackStamina = 12f; private const float AttackAdrenaline = 1f; private const float RangeMultiplier = 2f; private const float AttackDurationMultiplier = 1.75f; internal const float SwingSpeed = 0.5714286f; private const string SwingSource = "Battleaxe"; private const float HandOffsetZ = -0.4f; private const float RowingGripZ = -0.08f; private const float RowingGripRoll = -90f; private const float DefaultBladeTipZ = 2.8f; internal static void SetRowingGrip(GameObject handInstance, bool rowing) { //IL_0060: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)handInstance != (Object)null) ? handInstance.transform.Find("model") : null); if (!((Object)(object)val == (Object)null)) { if (!rowing) { val.localPosition = new Vector3(0f, 0f, -0.4f); val.localRotation = Quaternion.identity; } else { val.localPosition = new Vector3(0f, 0f, -0.08f); val.localRotation = Quaternion.Euler(0f, 0f, -90f); } } } internal static bool IsOar(ItemData item) { return KindOf(item) != null; } internal static bool IsDrakkarOar(ItemData item) { return KindOf(item) == s_drakkarOar; } internal static float BladeTipZ(ItemData item) { return KindOf(item)?.BladeTipZ ?? 2.8f; } internal static bool IsOarHash(int prefabHash) { return KindOf(prefabHash) != null; } internal static float BladeTipZ(int prefabHash) { return KindOf(prefabHash)?.BladeTipZ ?? 2.8f; } private static OarKind KindOf(int prefabHash) { OarKind[] array = s_kinds; foreach (OarKind oarKind in array) { if (StringExtensionMethods.GetStableHashCode(oarKind.PrefabName) == prefabHash) { return oarKind; } } return null; } private static OarKind KindOf(ItemData item) { if (item == null || (Object)(object)item.m_dropPrefab == (Object)null) { return null; } string name = ((Object)item.m_dropPrefab).name; OarKind[] array = s_kinds; foreach (OarKind oarKind in array) { if (oarKind.PrefabName == name) { return oarKind; } } return null; } internal static void Setup() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { PrefabManager.OnVanillaPrefabsAvailable -= Create; OarKind[] array = s_kinds; for (int i = 0; i < array.Length; i++) { Create(array[i]); } } private static void Create(OarKind kind) { //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_0011: 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_0028: 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_0041: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown ItemConfig val = new ItemConfig { Name = kind.Name, Description = kind.Description, CraftingStation = CraftingStations.Workbench, MinStationLevel = kind.StationLevel, Weight = kind.Weight }; RequirementConfig[] requirements = kind.Requirements; foreach (RequirementConfig val2 in requirements) { val.AddRequirement(val2); } CustomItem val3 = new CustomItem(kind.PrefabName, "Club", val); if ((Object)(object)val3.ItemPrefab == (Object)null) { Plugin.Log.LogError((object)("Failed to create the " + kind.Name + " item: couldn't clone 'Club' (not loaded yet?).")); return; } SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_maxDurability = kind.Durability; shared.m_attackForce = kind.Knockback; if (kind.Blunt > 0f) { SetBluntDamage(shared, kind.Blunt, kind.BluntMaxQuality); } shared.m_backstabBonus = 2f; MakeTwoHanded(shared); Attack attack = shared.m_attack; attack.m_attackStamina = kind.AttackStamina; attack.m_attackAdrenaline = 1f; attack.m_staggerMultiplier = 1.5f; attack.m_attackRange = ((kind.AttackRange > 0f) ? kind.AttackRange : (attack.m_attackRange * 2f)); ApplyOarVisual(val3.ItemPrefab, kind); Sprite val4 = ModAssets.LoadSprite(kind.Icon); if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogWarning((object)(kind.Name + " item: icon '" + kind.Icon + "' not in the bundle; rendering one from the model.")); val4 = RenderManager.Instance.Render(val3.ItemPrefab); } if ((Object)(object)val4 != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { val4 }; } if (!ItemManager.Instance.AddItem(val3)) { Plugin.Log.LogError((object)("Failed to register the " + kind.Name + " item with Jötunn.")); } else { Plugin.Log.LogInfo((object)($"{kind.Name} item registered: range {attack.m_attackRange:F2}, swing speed x{0.5714286f:F2}, " + $"durability {shared.m_maxDurability:F0}, knockback {shared.m_attackForce:F0}, " + $"blunt {shared.m_damages.m_blunt:F0} (+{shared.m_damagesPerLevel.m_blunt:F1}/level, max quality {shared.m_maxQuality}).")); } } private static void SetBluntDamage(SharedData shared, float blunt, float bluntMaxQuality) { //IL_0012: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(shared.m_maxQuality - 1, 0); shared.m_damages = new DamageTypes { m_blunt = blunt }; shared.m_damagesPerLevel = new DamageTypes { m_blunt = ((num > 0) ? ((bluntMaxQuality - blunt) / (float)num) : 0f) }; } private static void MakeTwoHanded(SharedData shared) { //IL_004b: 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) GameObject prefab = PrefabManager.Instance.GetPrefab("Battleaxe"); ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Oar item: 'Battleaxe' not found; keeping the Club's one-handed swings."); return; } SharedData shared2 = val.m_itemData.m_shared; shared.m_itemType = (ItemType)14; shared.m_animationState = shared2.m_animationState; CopySwing(shared2.m_attack, shared.m_attack); CopySwing(shared2.m_secondaryAttack, shared.m_secondaryAttack); } private static void CopySwing(Attack source, Attack target) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) target.m_attackType = source.m_attackType; target.m_attackAnimation = source.m_attackAnimation; target.m_attackRandomAnimations = source.m_attackRandomAnimations; target.m_attackChainLevels = source.m_attackChainLevels; target.m_attackOriginJoint = source.m_attackOriginJoint; target.m_attackAngle = source.m_attackAngle; target.m_attackRayWidth = source.m_attackRayWidth; target.m_attackHeight = source.m_attackHeight; target.m_attackOffset = source.m_attackOffset; } private static void ApplyOarVisual(GameObject itemPrefab, OarKind kind) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0101: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) GameObject val = ModAssets.LoadPrefab(kind.ModelPrefab); Transform val2 = (((Object)(object)val != (Object)null) ? val.transform : null); Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.Find("attach") : null); Transform val4 = itemPrefab.transform.Find("attach"); Transform val5 = (((Object)(object)val4 != (Object)null) ? val4.Find("model") : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val5 == (Object)null) { Plugin.Log.LogWarning((object)(kind.Name + " item: bundle prefab or the Club's attach/model not found; keeping the Club's own mesh.")); return; } Mesh sharedMesh = ((Component)val3).GetComponent<MeshFilter>().sharedMesh; MeshRenderer component = ((Component)val5).GetComponent<MeshRenderer>(); Material val6 = new Material(((Renderer)((Component)val3).GetComponent<MeshRenderer>()).sharedMaterial) { shader = ((Renderer)component).sharedMaterial.shader }; ((Component)val5).GetComponent<MeshFilter>().sharedMesh = sharedMesh; ((Renderer)component).sharedMaterials = (Material[])(object)new Material[1] { val6 }; Vector3 val7 = default(Vector3); ((Vector3)(ref val7))..ctor(0f, 0f, -0.4f); val5.localPosition = val7; val5.localRotation = Quaternion.identity; AddBackAttach(itemPrefab.transform, val4, val5, kind); BoxCollider componentInChildren = ((Component)val4).GetComponentInChildren<BoxCollider>(true); Bounds bounds; if ((Object)(object)componentInChildren != (Object)null) { ((Component)componentInChildren).transform.localPosition = val7; bounds = sharedMesh.bounds; componentInChildren.center = ((Bounds)(ref bounds)).center; bounds = sharedMesh.bounds; componentInChildren.size = ((Bounds)(ref bounds)).size; } foreach (Transform item in val3) { Transform val8 = item; Transform transform = new GameObject(((Object)val8).name).transform; transform.SetParent(val4, false); transform.localPosition = val8.localPosition + val7; transform.localRotation = val8.localRotation; } Transform val9 = val4.Find("equiped/trail"); Transform val10 = (((Object)(object)val9 != (Object)null) ? val9.Find("base") : null); Transform val11 = (((Object)(object)val9 != (Object)null) ? val9.Find("tip") : null); if ((Object)(object)val10 != (Object)null && (Object)(object)val11 != (Object)null) { val10.localPosition = val3.Find("fulcrum").localPosition + val7; val11.localPosition = val3.Find("blade_tip").localPosition + val7; } Transform val12 = val3.Find("blade_tip"); if ((Object)(object)val12 != (Object)null) { kind.BladeTipZ = val12.localPosition.z; } ManualLogSource log = Plugin.Log; object[] obj = new object[4] { kind.Name, ((Object)sharedMesh).name, null, null }; bounds = sharedMesh.bounds; obj[2] = ((Bounds)(ref bounds)).size.z; obj[3] = ((Object)val6.shader).name; log.LogInfo((object)string.Format("{0} item: model '{1}' ({2:F2} m) from the bundle, shader '{3}'.", obj)); } private static void AddBackAttach(Transform itemRoot, Transform attach, Transform model, OarKind kind) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0026: 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_006d: 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) GameObject val = new GameObject("attach_back"); val.SetActive(false); val.transform.SetParent(itemRoot, false); val.transform.localPosition = attach.localPosition; val.transform.localRotation = attach.localRotation; val.transform.SetSiblingIndex(attach.GetSiblingIndex()); Transform obj = Object.Instantiate<Transform>(model, val.transform, false); ((Object)obj).name = ((Object)model).name; obj.localPosition = kind.BackPosition; obj.localRotation = kind.BackRotation; } } internal static class OarSplash { private static readonly string[] s_sourceProjectiles = new string[3] { "bow_projectile", "bow_projectile_fire", "bow_projectile_frost" }; private static readonly FieldInfo s_hitWaterEffectsField = AccessTools.Field(typeof(Projectile), "m_hitWaterEffects"); private static readonly GameObject[] s_none = (GameObject[])(object)new GameObject[0]; private static GameObject[] s_prefabs; internal static void Play(Vector3 position) { //IL_001a: 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) if (Plugin.Splash.Value) { GameObject[] prefabs = GetPrefabs(); for (int i = 0; i < prefabs.Length; i++) { Object.Instantiate<GameObject>(prefabs[i], position, Quaternion.identity); } } } private static GameObject[] GetPrefabs() { if (s_prefabs != null) { return s_prefabs; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return s_none; } string[] array = s_sourceProjectiles; foreach (string text in array) { if (TryGetSplash(instance.GetPrefab(text), out s_prefabs)) { return s_prefabs; } } foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab != (Object)null && (((Object)prefab).name.StartsWith("bow_projectile") || ((Object)prefab).name.ToLowerInvariant().Contains("arrow")) && TryGetSplash(prefab, out s_prefabs)) { return s_prefabs; } } Plugin.Log.LogWarning((object)"No arrow water splash found in the game; the oar won't splash."); s_prefabs = s_none; return s_prefabs; } private static bool TryGetSplash(GameObject projectilePrefab, out GameObject[] prefabs) { prefabs = null; Projectile val = (((Object)(object)projectilePrefab != (Object)null) ? projectilePrefab.GetComponent<Projectile>() : null); EffectList val2 = (EffectList)(((Object)(object)val != (Object)null && s_hitWaterEffectsField != null) ? /*isinst with value type is only supported in some contexts*/: null); if (val2 == null || val2.m_effectPrefabs == null) { return false; } List<GameObject> list = new List<GameObject>(); EffectData[] effectPrefabs = val2.m_effectPrefabs; foreach (EffectData val3 in effectPrefabs) { if (val3 != null && val3.m_enabled && (Object)(object)val3.m_prefab != (Object)null && (Object)(object)val3.m_prefab.GetComponent<ZNetView>() == (Object)null) { list.Add(val3.m_prefab); } } if (list.Count == 0) { return false; } prefabs = list.ToArray(); Plugin.Log.LogInfo((object)("Oar splash: the " + ((Object)projectilePrefab).name + " water hit effect (" + string.Join(", ", list.ConvertAll((GameObject p) => ((Object)p).name)) + ").")); return true; } } internal static class OarSwing { private static readonly FieldInfo s_characterField = AccessTools.Field(typeof(CharacterAnimEvent), "m_character"); private static readonly FieldInfo s_animatorField = AccessTools.Field(typeof(CharacterAnimEvent), "m_animator"); private static readonly HashSet<CharacterAnimEvent> s_slowed = new HashSet<CharacterAnimEvent>(); internal static void OnFixedUpdate(CharacterAnimEvent animEvent) { if (!TryGetOarAttackAnimator(animEvent, out var animator)) { s_slowed.Remove(animEvent); } else if (s_slowed.Add(animEvent)) { Animator obj = animator; obj.speed *= 0.5714286f; } } internal static void OnSpeedSet(CharacterAnimEvent animEvent) { if (s_slowed.Contains(animEvent) && TryGetOarAttackAnimator(animEvent, out var animator)) { Animator obj = animator; obj.speed *= 0.5714286f; } } private static bool TryGetOarAttackAnimator(CharacterAnimEvent animEvent, out Animator animator) { animator = null; if (s_characterField == null || s_animatorField == null) { return false; } object? value = s_characterField.GetValue(animEvent); Humanoid val = (Humanoid)((value is Humanoid) ? value : null); if ((Object)(object)val == (Object)null || !((Character)val).IsOwner() || !((Character)val).InAttack() || !OarItem.IsOar(val.GetCurrentWeapon())) { return false; } object? value2 = s_animatorField.GetValue(animEvent); animator = (Animator)((value2 is Animator) ? value2 : null); return (Object)(object)animator != (Object)null; } } internal class OarVisual : MonoBehaviour { private const float GunwaleProbeTop = 1.5f; private const float GunwaleProbeBottom = -0.5f; private const float GunwaleProbeStep = 0.1f; private const float HullProbeDistance = 10f; private const float HullThickness = 0.15f; private static readonly List<Vector3> s_hullHits = new List<Vector3>(); private const float FallbackSideOffset = 0.6f; private const float FallbackHeight = 0.6f; private const float RelocateDistance = 0.3f; private const float DefaultSeaLevel = 30f; private const float NoWater = -1000f; private static readonly FieldInfo s_rightItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_rightItemInstance"); private static readonly FieldInfo s_rightItemHashField = AccessTools.Field(typeof(VisEquipment), "m_currentRightItemHash"); private Player _player; private VisEquipment _visEquipment; private RowerAnimation _animation; private Ship _ship; private ZDOID _shipId = ZDOID.None; private ZDOID _missingShipLogged = ZDOID.None; private bool _fitted; private Vector3 _localRowerPosition; private Vector3 _localGunwalePoint; private Transform _turnedVisual; private ShipFit _fit; private float _side = 1f; private Transform _spine; private Quaternion _spinePosed; private Quaternion _spineLeant; private GameObject _rowingGripInstance; private bool _rowingGripMirrored; private bool _bladeWet; private bool _bladeTracked; private WaterVolume _waterVolume; internal Ship RowingShip => ResolveRowingShip(); private void Awake() { _player = ((Component)this).GetComponent<Player>(); _visEquipment = ((Component)this).GetComponent<VisEquipment>(); _animation = new RowerAnimation(_player); } private void Update() { //IL_001e: 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) Ship val = ResolveRowingShip(); bool flag = (Object)(object)val != (Object)null; bool mirrored = flag && ((Component)val).transform.InverseTransformPoint(((Component)this).transform.position).x < 0f; _animation.Update(flag, flag ? RowingController.GetRowingGear(_player) : RowingGear.Stop, mirrored); UpdateGrip(flag, mirrored); } private void LateUpdate() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Ship ship = _ship; if ((Object)(object)ship == (Object)null) { _fitted = false; FaceForward(); return; } Vector3 val = ((Component)ship).transform.InverseTransformPoint(((Component)this).transform.position); if (_fitted) { Vector3 val2 = val - _localRowerPosition; if (!(((Vector3)(ref val2)).sqrMagnitude > 0.09f)) { goto IL_0060; } } FitToShip(ship, val); goto IL_0060; IL_0060: if (Plugin.DebugSkipFaceStern.Value) { FaceForward(); } else { FaceStern(ship); } if (!Plugin.DebugSkipLean.Value) { LeanOverGunwale(ship); } TrackSplash(); } private void OnDestroy() { FaceForward(); _animation.Destroy(); } private void TrackSplash() { //IL_004e: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0086: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)_rowingGripInstance != (Object)null) ? _rowingGripInstance.transform.Find("model") : null); if ((Object)(object)val == (Object)null) { _bladeTracked = false; return; } Vector3 val2 = val.TransformPoint(0f, 0f, OarItem.BladeTipZ(HeldItemHash())); float num = WaterLevel(val2); bool flag = val2.y < num; if (flag && !_bladeWet && _bladeTracked) { OarSplash.Play(new Vector3(val2.x, num, val2.z)); } _bladeWet = flag; _bladeTracked = true; } private float WaterLevel(Vector3 world) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f); float waterLevel = Floating.GetWaterLevel(new Vector3(world.x, num, world.z), ref _waterVolume); if (!(waterLevel > -1000f)) { return num; } return waterLevel; } private void UpdateGrip(bool rowing, bool mirrored) { GameObject val = (GameObject)((s_rightItemInstanceField != null && (Object)(object)_visEquipment != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if (rowing && (Object)(object)val != (Object)null && OarItem.IsOarHash(HeldItemHash())) { if ((Object)(object)val != (Object)(object)_rowingGripInstance || mirrored != _rowingGripMirrored) { OarItem.SetRowingGrip(val, rowing: true); Transform val2 = (mirrored ? _visEquipment.m_leftHand : _visEquipment.m_rightHand); if ((Object)(object)val2 != (Object)null) { val.transform.SetParent(val2, false); } _rowingGripInstance = val; _rowingGripMirrored = mirrored; if (Plugin.DebugRowingSync.Value) { Plugin.Log.LogInfo((object)("[sync] " + _player.GetPlayerName() + ": oar in the rowing grip, " + (mirrored ? "left" : "right") + " hand")); } } } else { if ((Object)(object)_rowingGripInstance != (Object)null) { ReleaseGrip(_rowingGripInstance); } _rowingGripInstance = null; } } private int HeldItemHash() { if (s_rightItemHashField != null && (Object)(object)_visEquipment != (Object)null) { object value = s_rightItemHashField.GetValue(_visEquipment); if (value is int) { return (int)value; } } return 0; } private void ReleaseGrip(GameObject instance) { OarItem.SetRowingGrip(instance, rowing: false); if ((Object)(object)_visEquipment != (Object)null && (Object)(object)_visEquipment.m_rightHand != (Object)null) { instance.transform.SetParent(_visEquipment.m_rightHand, false); } } internal bool TryGetGunwalePoint(out Vector3 point) { //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_0030: 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) if (!_fitted || (Object)(object)_ship == (Object)null) { point = Vector3.zero; return false; } point = ((Component)_ship).transform.TransformPoint(_localGunwalePoint); return true; } private Ship ResolveRowingShip() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player == (Object)null) { return null; } ZDOID rowingShip = RowingController.GetRowingShip(_player); if (rowingShip == ZDOID.None) { _shipId = ZDOID.None; _ship = null; return null; } if (rowingShip != _shipId || (Object)(object)_ship == (Object)null) { _shipId = rowingShip; GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(rowingShip) : null); _ship = (((Object)(object)val != (Object)null) ? val.GetComponent<Ship>() : null); _fitted = false; } if ((Object)(object)_ship == (Object)null && Plugin.DebugRowingSync.Value && rowingShip != _missingShipLogged) { _missingShipLogged = rowingShip; Plugin.Log.LogInfo((object)$"[sync] {_player.GetPlayerName()}: rowing ship {rowingShip} not found in this client's scene"); } return _ship; } private void FitToShip(Ship ship, Vector3 localRower) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) _localRowerPosition = localRower; float num = (_side = ((localRower.x >= 0f) ? 1f : (-1f))); _fit = ShipFit.For(ship); float halfWidth; float top; bool flag = TryFindGunwale(ship, localRower, num, out halfWidth, out top); _localGunwalePoint = (Vector3)(flag ? new Vector3(num * halfWidth, top, localRower.z) : (localRower + new Vector3(num * 0.6f, 0.6f, 0f))); Plugin.Log.LogInfo((object)($"Rower on {((Object)ship).name}: at {localRower:F2}, gunwale " + (flag ? $"{halfWidth:F2} wide, top {top:F2}" : "not found") + " (ship space).")); _fitted = true; } private void FaceStern(Ship ship) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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) GameObject visual = ((Character)_player).GetVisual(); if (!((Object)(object)visual == (Object)null)) { Vector3 up = ((Component)this).transform.up; Vector3 val = Vector3.ProjectOnPlane(-((Component)ship).transform.forward, up); if (!(((Vector3)(ref val)).sqrMagnitude < 1E-06f)) { _turnedVisual = visual.transform; _turnedVisual.rotation = Quaternion.LookRotation(val, up); float num = ((_fit != null) ? _fit.Outboard : 0f); _turnedVisual.position = ((Component)this).transform.position + ((Component)ship).transform.right * (_side * num); } } } private void LeanOverGunwale(Ship ship) { //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_0090: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) float num = ((_fit != null) ? _fit.Lean : 0f); if (num != 0f && TryGetSpine(out var spine)) { if (spine.localRotation != _spineLeant) { _spinePosed = spine.localRotation; } spine.localRotation = _spinePosed; Vector3 val = ((Component)ship).transform.right * _side; Vector3 val2 = Vector3.Cross(((Component)ship).transform.up, val); spine.rotation = Quaternion.AngleAxis(num, val2) * spine.rotation; _spineLeant = spine.localRotation; } } private bool TryGetSpine(out Transform spine) { if ((Object)(object)_spine == (Object)null) { GameObject visual = ((Character)_player).GetVisual(); Animator val = (((Object)(object)visual != (Object)null) ? visual.GetComponentInChildren<Animator>() : null); _spine = (((Object)(object)val != (Object)null && val.isHuman) ? val.GetBoneTransform((HumanBodyBones)7) : null); } spine = _spine; return (Object)(object)spine != (Object)null; } private void FaceForward() { //IL_0014: 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) if ((Object)(object)_turnedVisual != (Object)null) { _turnedVisual.localRotation = Quaternion.identity; _turnedVisual.localPosition = Vector3.zero; } _turnedVisual = null; } private bool TryFindGunwale(Ship ship, Vector3 localRower, float side, out float halfWidth, out float top) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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) Transform transform = ((Component)ship).transform; Rigidbody component = ((Component)ship).GetComponent<Rigidbody>(); Transform ignore = (((Object)(object)ship.m_rudderObject != (Object)null) ? ship.m_rudderObject.transform : null); Vector3 direction = transform.TransformDirection(Vector3.left * side); s_hullHits.Clear(); Vector3 val = default(Vector3); for (float num = 1.5f; num >= -0.5f; num -= 0.1f) { ((Vector3)(ref val))..ctor(side * 10f, localRower.y + num, localRower.z); if (TryHitHull(transform.TransformPoint(val), direction, component, ignore, out var point)) { s_hullHits.Add(transform.InverseTransformPoint(point)); } } halfWidth = -1f; top = float.MinValue; foreach (Vector3 s_hullHit in s_hullHits) { halfWidth = Mathf.Max(halfWidth, Mathf.Abs(s_hullHit.x)); } foreach (Vector3 s_hullHit2 in s_hullHits) { if (Mathf.Abs(s_hullHit2.x) > halfWidth - 0.15f) { top = Mathf.Max(top, s_hullHit2.y); } } return s_hullHits.Count > 0; } private static bool TryHitHull(Vector3 origin, Vector3 direction, Rigidbody shipBody, Transform ignore, out Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_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) point = Vector3.zero; float num = float.MaxValue; RaycastHit[] array = Physics.RaycastAll(origin, direction, 10f, -5, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody != (Object)(object)shipBody) && !(((RaycastHit)(ref val)).distance >= num) && (!((Object)(object)ignore != (Object)null) || !((RaycastHit)(ref val)).transform.IsChildOf(ignore))) { num = ((RaycastHit)(ref val)).distance; point = ((RaycastHit)(ref val)).point; } } return num < float.MaxValue; } } [BepInPlugin("com.fabenejr.vikingoarsmen", "Viking Oarsmen", "3.4.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.fabenejr.vikingoarsmen"; public const string PluginName = "Viking Oarsmen"; public const string PluginVersion = "3.4.0"; internal static ManualLogSource Log; internal static ConfigEntry<float> PowerPerRower; internal static ConfigEntry<float> Gear2Multiplier; internal static ConfigEntry<float> Gear3Multiplier; internal static ConfigEntry<float> ReverseMultiplier; internal static ConfigEntry<float> MaxRowingPower; internal static ConfigEntry<float> MaxRowingSpeed; internal static ConfigEntry<float> CrewFalloff; internal static ConfigEntry<float> SteeringMultiplier; internal static ConfigEntry<float> RampUpTime; internal static ConfigEntry<float> StaminaDrainAmount; internal static ConfigEntry<float> StaminaDrainIntervalSlow; internal static ConfigEntry<float> StaminaDrainIntervalHalf; internal static ConfigEntry<float> StaminaDrainIntervalFull; internal static ConfigEntry<bool> ShowOarHint; internal static ConfigEntry<float> StrokeSpeed; internal static ConfigEntry<bool> Splash; internal static ConfigEntry<bool> ShowCrewHud; internal static ConfigEntry<bool> RowingSound; internal static ConfigEntry<float> RowingSoundVolume; internal static ConfigEntry<bool> DebugRowingSync; internal static ConfigEntry<bool> DebugSkipFaceStern; internal static ConfigEntry<bool> DebugSkipLean; private Harmony _harmony; private ConfigEntry<T> BindSynced<T>(string section, string key, T defaultValue, string description, AcceptableValueBase range = null) { //IL_0015: 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_0022: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); } private void Awake() { //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PowerPerRower = BindSynced("Physics", "PowerPerRower", 0.08f, "Share of the maximum thrust a rower in Slow gear (1) adds. 0.25 = four rowers in Slow gear reach full speed."); Gear2Multiplier = BindSynced("Physics", "Gear2Multiplier", 1.4f, "Thrust in Half gear (2), as a multiple of PowerPerRower."); Gear3Multiplier = BindSynced("Physics", "Gear3Multiplier", 1.8f, "Thrust in Full gear (3), as a multiple of PowerPerRower."); ReverseMultiplier = BindSynced("Physics", "ReverseMultiplier", -1f, "Thrust in reverse, as a multiple of PowerPerRower. Negative pushes the ship backward."); MaxRowingPower = BindSynced("Physics", "MaxRowingPower", 1.5f, "Maximum total rowing thrust, ahead or astern. 1.0 = same as a full sail with a strong tailwind."); MaxRowingSpeed = BindSynced("Physics", "MaxRowingSpeed", 0f, "Speed in m/s (along the bow) above which rowing stops adding thrust, so oars and sail can't stack without limit. 0 = no limit."); CrewFalloff = BindSynced("Physics", "CrewFalloff", 0f, "How much each extra rower adds less than the one before, from 0 (every rower adds the same) to 0.5. With 0.1 the second rower adds 90%, the third 81%, and so on; the strongest strokes count first.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f)); SteeringMultiplier = BindSynced("Physics", "SteeringMultiplier", 0f, "How strongly rowing turns the ship. 0 = off. Above 0 the ship turns away from the side the rowers sit on, and the other way when rowing in reverse; rowers on both sides cancel out. Negative values turn it towards that side."); RampUpTime = BindSynced("Physics", "RampUpTime", 1.5f, "Seconds for the rowing thrust to reach a new target (crew changes, gear shifts, stopping)."); StaminaDrainAmount = BindSynced("Gameplay", "StaminaDrainAmount", 6f, "Stamina spent on every stroke in any gear but neutral. Set to 0 to disable the cost entirely."); StaminaDrainIntervalSlow = BindSynced("Gameplay", "StaminaDrainIntervalSlow", 2f, "Seconds between strokes in Slow gear (1) and reverse."); StaminaDrainIntervalHalf = BindSynced("Gameplay", "StaminaDrainIntervalHalf", 1.5f, "Seconds between strokes in Half gear (2)."); StaminaDrainIntervalFull = BindSynced("Gameplay", "StaminaDrainIntervalFull", 1f, "Seconds between strokes in Full gear (3)."); ShowOarHint = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "ShowOarHint", true, "Show the \"Equip the oar to row.\" message (and the Drakkar Oar one) when you sit on a bench without the right oar and press W or S."); StrokeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "StrokeSpeed", 1f, "Speed of the rowing animation in every gear. 1.0 = the animation's own pace in Half gear (2); Slow and reverse are slower, Full faster."); Splash = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "Splash", true, "Splash and play a sound when the oar blade hits the water."); ShowCrewHud = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowCrewHud", true, "While you row, show a panel with how many aboard are rowing and a top-down drawing of the ship with where each of them sits."); RowingSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "RowingSound", true, "Play the sound of the oars on every stroke: a lone rower's, or the whole crew's when two or more row together."); RowingSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "RowingSoundVolume", 1f, new ConfigDescription("Volume of the rowing sound, relative to the game's sound effects volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); DebugRowingSync = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugRowingSync", false, "Log every rower's stroke phase against the crew's beat to BepInEx/LogOutput.log, to track down rowers whose animation drifts or stalls in multiplayer."); DebugSkipFaceStern = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugSkipFaceStern", false, "Do not turn the rower to face the stern. Only to find out what makes the cape or head jitter while rowing; the rower then faces the way the bench does."); DebugSkipLean = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugSkipLean", false, "Do not lean the rower over the gunwale. Only to find out what makes the cape or head jitter while rowing."); _harmony = new Harmony("com.fabenejr.vikingoarsmen"); _harmony.PatchAll(); OarItem.Setup(); Log.LogInfo((object)"Viking Oarsmen v3.4.0 loaded. Equip the oar and sit on a ship bench to row."); } private void Update() { RowingController.Update(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class RaftSeat { private const string RaftPrefab = "Raft"; private const string StoolSource = "VikingShip"; private const string StoolPath = "interactive/sit_box (1)"; private const string SeatName = "VikingOarsmen_sit_box"; private static readonly Vector3 s_seatPosition = new Vector3(-1.1f, 0.48f, 1.9f); internal static void AddTo(Ship ship) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (!(Utils.GetPrefabName(((Component)ship).gameObject) != "Raft")) { Transform val = ((Component)ship).transform.Find("interactive"); GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("VikingShip") : null); Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.transform.Find("interactive/sit_box (1)") : null); if ((Object)(object)val == (Object)null || (Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"Couldn't add the raft bench: raft interactive or VikingShip stool not found."); } else if (!((Object)(object)val.Find("VikingOarsmen_sit_box") != (Object)null)) { GameObject obj = Object.Instantiate<GameObject>(((Component)val3).gameObject, val, false); ((Object)obj).name = "VikingOarsmen_sit_box"; obj.transform.localPosition = s_seatPosition; obj.transform.localRotation = Quaternion.identity; } } } } internal class RowerAnimation { private const float BlendTime = 0.3f; private const float SyncTime = 0.5f; private const float MaxCatchUp = 0.5f; private const float DebugInterval = 1f; private readonly Player _player; private PlayableGraph _graph; private AnimationPlayableOutput _output; private AnimationMixerPlayable _mixer; private AnimationClipPlayable _idle; private AnimationClipPlayable _stroke; private float _weight; private float _strokeWeight; private float _phase; private bool _mirrored; private float _rate; private float _gap; private float _speed = 1f; private float _debugTimer; internal RowerAnimation(Player player) { _player = player; } internal void Update(bool rowing, RowingGear gear, bool mirrored) { //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) AnimationClip val = ModAssets.RowIdle(mirrored); AnimationClip val2 = ModAssets.RowStroke(mirrored); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } if (((PlayableGraph)(ref _graph)).IsValid() && mirrored != _mirrored) { DebugLog("seat side changed, rebuilding the graph"); Destroy(); } _weight = Mathf.MoveTowards(_weight, rowing ? 1f : 0f, Time.deltaTime / 0.3f); if (_weight <= 0f) { Destroy(); return; } float num = RowingBeat.StrokeRate(gear, val2.length); if (!((PlayableGraph)(ref _graph)).IsValid()) { if (!Create(val, val2, num)) { return; } _mirrored = mirrored; } bool flag = rowing && gear != RowingGear.Stop; _strokeWeight = Mathf.MoveTowards(_strokeWeight, flag ? 1f : 0f, Time.deltaTime / 0.3f); if (_rate <= 0f && num > 0f) { _phase = RowingBeat.GetBeat(num); DebugLog($"stroke starts in {gear}: phase set to the beat {_phase:F2}"); } else if (num > 0f && !Mathf.Approximately(num, _rate)) { DebugLog($"pace {_rate:F3} -> {num:F3} ({gear}): {BeatGap(num):F2} off the beat"); } _rate = num; AdvancePhase(num); float num2 = ((gear == RowingGear.Back) ? (1f - _phase) : _phase); PlayableExtensions.SetTime<AnimationClipPlayable>(_idle, (double)Mathf.Repeat(Time.time, val.length)); PlayableExtensions.SetTime<AnimationClipPlayable>(_stroke, (double)(num2 * val2.length)); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(_mixer, 0, 1f - _strokeWeight); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(_mixer, 1, _strokeWeight); PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(_output, _weight); if (Plugin.DebugRowingSync.Value) { _debugTimer -= Time.deltaTime; if (_debugTimer <= 0f) { _debugTimer = 1f; DebugLog($"{gear} rate {num:F3} phase {_phase:F2} beat {((num > 0f) ? RowingBeat.GetBeat(num) : 0f):F2} " + $"gap {_gap:F2} speed x{_speed:F2} weight {_weight:F2} stroke {_strokeWeight:F2} mirrored {_mirrored}"); } } } internal void Destroy() { if (((PlayableGraph)(ref _graph)).IsValid()) { DebugLog("graph destroyed"); ((PlayableGraph)(ref _graph)).Destroy(); } _strokeWeight = 0f; _rate = 0f; } private bool Create(AnimationClip idle, AnimationClip stroke, float rate) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_009c: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) GameObject visual = ((Character)_player).GetVisual(); Animator val = (((Object)(object)visual != (Object)null) ? visual.GetComponentInChildren<Animator>() : null); if ((Object)(object)val == (Object)null || !val.isHuman) { return false; } _graph = PlayableGraph.Create("VikingOarsmen_Rowing"); ((PlayableGraph)(ref _graph)).SetTimeUpdateMode((DirectorUpdateMode)1); _idle = AnimationClipPlayable.Create(_graph, idle); _stroke = AnimationClipPlayable.Create(_graph, stroke); PlayableExtensions.SetSpeed<AnimationClipPlayable>(_idle, 0.0); PlayableExtensions.SetSpeed<AnimationClipPlayable>(_stroke, 0.0); _mixer = AnimationMixerPlayable.Create(_graph, 2); ((PlayableGraph)(ref _graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(_idle, 0, _mixer, 0); ((PlayableGraph)(ref _graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(_stroke, 0, _mixer, 1); _output = AnimationPlayableOutput.Create(_graph, "Rowing", val); PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationMixerPlayable>(_output, _mixer); PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(_output, 0f); ((PlayableGraph)(ref _graph)).Play(); _phase = ((rate > 0f) ? RowingBeat.GetBeat(rate) : 0f); _rate = rate; DebugLog($"graph created, phase {_phase:F2}, pace {rate:F3}"); return true; } private void AdvancePhase(float rate) { if (!(rate <= 0f)) { float phase = _phase; float deltaTime = Time.deltaTime; _phase = Mathf.Repeat(_phase + deltaTime * rate, 1f); float num = BeatGap(rate); float num2 = Mathf.Clamp(num * Mathf.Clamp01(deltaTime / 0.5f), -0.5f * rate * deltaTime, 0.5f * rate * deltaTime); _phase = Mathf.Repeat(_phase + num2, 1f); _gap = num; if (deltaTime > 0f) { _speed = (Mathf.Repeat(_phase - phase + 0.5f, 1f) - 0.5f) / (deltaTime * rate); } } } private float BeatGap(float rate) { return Mathf.Repeat(RowingBeat.GetBeat(rate) - _phase + 0.5f, 1f) - 0.5f; } private void DebugLog(string message) { if (Plugin.DebugRowingSync.Value) { string text = (((Object)(object)_player != (Object)null) ? _player.GetPlayerName() : "?"); string text2 = (((Object)(object)_player == (Object)(object)Player.m_localPlayer) ? "local" : "remote"); double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : (-1.0)); Plugin.Log.LogInfo((object)$"[sync] {text} ({text2}) t={num:F2}: {message}"); } } } internal static class RowingBeat { private const float SlowPace = 0.75f; private const float HalfPace = 1f; private const float FullPace = 1.3f; internal static float StrokeRate(RowingGear gear, float clipLength) { float num; switch (gear) { case RowingGear.Back: case RowingGear.Slow: num = 0.75f; break; case RowingGear.Half: num = 1f; break; case RowingGear.Full: num = 1.3f; break; default: return 0f; } return Mathf.Max(0f, Plugin.StrokeSpeed.Value) * num / Mathf.Max(clipLength, 0.01f); } internal static float GetBeat(float rate) { double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : ((double)Time.time)) * (double)rate; return (float)(num - Math.Floor(num)); } } internal static class RowingController { private const string RowingShipKey = "VikingOarsmen_RowingShip"; private const string RowingGearKey = "VikingOarsmen_Gear"; private const string DrakkarPrefab = "VikingShip_Ashlands"; private const string HoldfastName = "$ship_holdfast"; private static RowingGear s_desiredGear; private static bool s_suspended; private static float s_staminaTimer; private const float PressThreshold = 0.6f; private const float ReleaseThreshold = 0.3f; private static bool s_forwardHeld; private static bool s_backwardHeld; private static bool s_forwardPressed; private static bool s_backwardPressed; internal static void ReadMoveInput(Vector3 movedir) { //IL_0005: 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) s_forwardPressed |= Press(movedir.z, ref s_forwardHeld); s_backwardPressed |= Press(0f - movedir.z, ref s_backwardHeld); } private static bool Press(float axis, ref bool held) { bool flag = axis > (held ? 0.3f : 0.6f); bool result = flag && !held; held = flag; return result; } internal static void Update() { bool flag = s_forwardPressed; bool flag2 = s_backwardPressed; s_forwardPressed = false; s_backwardPressed = false; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { s_desiredGear = RowingGear.Stop; return; } Ship seatShip = GetSeatShip(localPlayer); bool flag3 = (Object)(object)seatShip != (Object)null && IsOnBench(localPlayer) && !((Character)localPlayer).IsDead(); bool flag4 = HasOarFor(localPlayer, seatShip); bool flag5 = CanTakeGameplayInput(); if (!flag3 || !flag4) { if (Plugin.ShowOarHint.Value && flag3 && !flag4 && flag5 && (flag || flag2)) { ((Character)localPlayer).Message((MessageType)2, OarItem.IsOar(((Humanoid)localPlayer).GetCurrentWeapon()) ? "This oar can't reach the water from here. Equip the Drakkar Oar." : "Equip the oar to row.", 0, (Sprite)null, false); } s_desiredGear = RowingGear.Stop; s_suspended = false; SetRowingGear(localPlayer, RowingGear.Stop); SetRowingShip(localPlayer, null); return; } if (flag5 && ZInput.GetButtonDown("Use")) { ((Character)localPlayer).AttachStop(); return; } RowingGear rowingGear = s_desiredGear; if (flag5) { if (flag) { s_desiredGear = StepForward(s_desiredGear); } else if (flag2) { s_desiredGear = StepBackward(s_desiredGear); } } bool flag6 = s_desiredGear != rowingGear; if (flag6) { Plugin.Log.LogDebug((object)$"Gear {rowingGear} -> {s_desiredGear}"); } RowingGear gear = ResolveEffectiveGear(localPlayer, flag6); SetRowingGear(localPlayer, gear); SetRowingShip(localPlayer, seatShip); } internal static ZDOID GetRowingShip(Player player) { //IL_0018: 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) ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return ZDOID.None; } return component.GetZDO().GetZDOID("VikingOarsmen_RowingShip"); } internal static RowingGear GetRowingGear(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return RowingGear.Stop; } return (RowingGear)component.GetZDO().GetInt("VikingOarsmen_Gear", 0); } internal static RowingGear GetSelectedGear() { return s_desiredGear; } private static void SetRowingGear(Player player, RowingGear gear) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { ZDO zDO = component.GetZDO(); if (zDO.GetInt("VikingOarsmen_Gear", 0) != (int)gear) { zDO.Set("VikingOarsmen_Gear", (int)gear); } } } internal static bool IsRowingMode(Player player) { Ship seatShip = GetSeatShip(player); if ((Object)(object)seatShip != (Object)null && !((Character)player).IsDead() && IsOnBench(player)) { return HasOarFor(player, seatShip); } return false; } private static Ship GetSeatShip(Player player) { if (!((Character)player).IsAttachedToShip()) { return null; } Transform attachPoint = player.GetAttachPoint(); if (!((Object)(object)attachPoint != (Object)null)) { return null; } return ((Component)attachPoint).GetComponentInParent<Ship>(); } private static bool IsOnBench(Player player) { if (!((Character)player).IsAttachedToShip() || player.GetDoodadController() != null) { return false; } Transform attachPoint = player.GetAttachPoint(); Chair val = (((Object)(object)attachPoint != (Object)null) ? ((Component)attachPoint).GetComponentInParent<Chai