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 SailingProgression v0.1.6
plugins/SailingProgression/SailingProgression.dll
Decompiled 4 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SailingProgression")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.6.0")] [assembly: AssemblyInformationalVersion("0.1.6")] [assembly: AssemblyProduct("SailingProgression")] [assembly: AssemblyTitle("SailingProgression")] [assembly: AssemblyVersion("0.1.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 SailingProgression { public static class Balance { public static float Level(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return Math.Max(0f, Math.Min(100f, value)); } return 0f; } public static float BonusPercent(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return Math.Max(0f, Math.Min(100f, value)); } return 0f; } public static float SpeedTarget(float level, float maximumPercent = 40f) { float num = Level(level); return 1f + (0.015f * Math.Min(num, 50f) + 0.005f * Math.Max(num - 50f, 0f)) * BonusPercent(maximumPercent) / 100f; } public static float SailForce(float level, float maximumPercent = 40f) { return SpeedTarget(level, maximumPercent) * SpeedTarget(level, maximumPercent); } public static float Endurance(float level, float maximumPercent = 30f) { return 1f + BonusPercent(maximumPercent) / 100f * Level(level) / 100f; } public static bool ValidSample(float seconds, float distance) { if (seconds >= 0.75f && seconds <= 2f && distance >= 0f) { return distance <= 20f * seconds; } return false; } public static float ExperienceMultiplier(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return Math.Max(1f, Math.Min(10f, value)); } return 1f; } public static bool ValidJourney(float seconds, float netDistance) { if (seconds >= 10f && netDistance >= seconds && netDistance <= 20f * seconds && !float.IsNaN(netDistance)) { return !float.IsInfinity(netDistance); } return false; } public static bool ValidTravel(float seconds, float horizontalDistance, float speed) { if (seconds >= 0.75f && seconds <= 2f && horizontalDistance >= 0.75f * seconds && horizontalDistance <= 20f * seconds && Math.Abs(speed) >= 0.75f && !float.IsNaN(horizontalDistance)) { return !float.IsInfinity(horizontalDistance); } return false; } } [BepInPlugin("branchofyore.sailingprogression", "Sailing Progression", "0.1.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(Ship), "GetSailForce")] private static class SailPatch { private static void Postfix(Ship __instance, ref Vector3 __result) { //IL_000a: 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_002e: Unknown result type (might be due to invalid IL or missing references) if (__instance.IsOwner()) { __result *= Balance.SailForce(CaptainLevel(__instance), instance.MaximumSpeedBonus.Value); } } } [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] private static class HullPatch { private static void Prefix(WearNTear __instance, ref float damage) { Ship component = ((Component)__instance).GetComponent<Ship>(); if (Object.op_Implicit((Object)(object)component) && component.IsOwner() && damage > 0f) { damage /= Balance.Endurance(CaptainLevel(component), instance.MaximumEnduranceBonus.Value); } } } [HarmonyPatch(typeof(Ship), "CustomFixedUpdate")] private static class RowingPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { FieldInfo field = AccessTools.Field(typeof(Ship), "m_backwardForce"); MethodInfo replacement = AccessTools.Method(typeof(Plugin), "RowingForce", (Type[])null, (Type[])null); int replaced = 0; foreach (CodeInstruction instruction in instructions) { CodeInstruction val = new CodeInstruction(instruction); if (CodeInstructionExtensions.LoadsField(val, field, false)) { val.opcode = OpCodes.Call; val.operand = replacement; replaced++; } yield return val; } if (replaced != 2) { throw new InvalidOperationException("Unsupported Ship rowing code: expected two propulsion reads."); } } } public const string Id = "branchofyore.sailingprogression"; public const string LevelKey = "branchofyore.sailingprogression.level"; private static Plugin instance = null; private Harmony harmony; private Player? sampledPlayer; private Ship? sampledShip; private Vector3 previousPosition; private Vector3 journeyStart; private float nextSample; private float previousTime; private float qualifyingSeconds; private static readonly FieldRef<Ship, List<Player>> Players = AccessTools.FieldRefAccess<Ship, List<Player>>("m_players"); public static SkillType Sailing { get; private set; } public ConfigEntry<float> ExperienceMultiplier { get; private set; } public ConfigEntry<float> MaximumSpeedBonus { get; private set; } public ConfigEntry<float> MaximumEnduranceBonus { get; private set; } private void Awake() { //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_0045: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0086: 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_0093: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00d4: 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_00e1: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown instance = this; MaximumSpeedBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Bonuses", "Maximum Speed Bonus", 40f, new ConfigDescription("Maximum speed bonus in percent at Sailing level 100, for sails and rowing (including reverse). Level 50 receives 75% of this bonus. Default 40 means +30% at level 50 and approximately +40% at level 100. Server synchronized.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); MaximumEnduranceBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Bonuses", "Maximum Endurance Bonus", 30f, new ConfigDescription("Extra damage the hull can endure, in percent at Sailing level 100. Scales evenly with skill level. Default 30 means +15% at level 50 and +30% at level 100. Does not repair the boat. Server synchronized.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); ExperienceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "Sailing XP Multiplier", 1f, new ConfigDescription("Sailing experience for everyone aboard. 1 = normal, 10 = ten times the experience. The server value applies to all players. Does not change speed or endurance per level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); Texture2D val = new Texture2D(2, 2); using (Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("SailingProgression.Icon.png")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); AssetUtils.LoadImage(val, memoryStream.ToArray()); } Sprite icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); Sailing = SkillManager.Instance.AddSkill(new SkillConfig { Identifier = "branchofyore.sailingprogression.sailing", Name = "Sailing", Description = "Sailing speed and endurance", IncreaseStep = 1f, Icon = icon }); harmony = new Harmony("branchofyore.sailingprogression"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sailing Progression 0.1.6 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static Player? Captain(Ship ship) { if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ship.m_shipControlls)) { return null; } long user = ship.m_shipControlls.GetUser(); if (user == 0L) { return null; } foreach (Player item in Players.Invoke(ship)) { if (Object.op_Implicit((Object)(object)item) && !((Character)item).IsDead() && item.GetPlayerID() == user) { return item; } } return null; } public static float CaptainLevel(Ship ship) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) Player val = Captain(ship); if (!Object.op_Implicit((Object)(object)val)) { return 0f; } if ((Object)(object)val == (Object)(object)Player.m_localPlayer) { return Balance.Level(((Character)val).GetSkills().GetSkillLevel(Sailing)); } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return 0f; } return Balance.Level(component.GetZDO().GetFloat("branchofyore.sailingprogression.level", 0f)); } private void Update() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; if (time < nextSample) { return; } nextSample = time + 1f; Player localPlayer = Player.m_localPlayer; Ship localShip = Ship.GetLocalShip(); if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || !Object.op_Implicit((Object)(object)localShip) || !localShip.IsPlayerInBoat(localPlayer) || !Riding(localPlayer, localShip)) { ResetSample(); return; } ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner()) { ResetSample(); return; } component.GetZDO().Set("branchofyore.sailingprogression.level", Balance.Level(((Character)localPlayer).GetSkills().GetSkillLevel(Sailing))); Vector3 position = ((Component)localShip).transform.position; if ((Object)(object)sampledPlayer != (Object)(object)localPlayer || (Object)(object)sampledShip != (Object)(object)localShip) { sampledPlayer = localPlayer; sampledShip = localShip; previousPosition = position; previousTime = time; journeyStart = position; qualifyingSeconds = 0f; return; } float num = time - previousTime; Vector3 val = position - previousPosition; val.y = 0f; previousPosition = position; previousTime = time; if ((int)localShip.GetSpeedSetting() == 0 || !Balance.ValidSample(num, ((Vector3)(ref val)).magnitude)) { qualifyingSeconds = 0f; journeyStart = position; return; } qualifyingSeconds += num; if (!(qualifyingSeconds < 10f)) { Vector3 val2 = position - journeyStart; val2.y = 0f; bool num2 = Balance.ValidJourney(qualifyingSeconds, ((Vector3)(ref val2)).magnitude); qualifyingSeconds = 0f; journeyStart = position; if (num2) { ((Character)localPlayer).RaiseSkill(Sailing, 3f * Balance.ExperienceMultiplier(ExperienceMultiplier.Value)); component.GetZDO().Set("branchofyore.sailingprogression.level", Balance.Level(((Character)localPlayer).GetSkills().GetSkillLevel(Sailing))); } } } private void ResetSample() { sampledPlayer = null; sampledShip = null; qualifyingSeconds = 0f; } public static bool Riding(Player player, Ship ship) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00b2: 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) if ((object)player.GetDoodadController() == ship.m_shipControlls || (Object)(object)((Character)player).GetStandingOnShip() == (Object)(object)ship || (((Character)player).IsAttachedToShip() && Object.op_Implicit((Object)(object)player.GetAttachPoint()) && (Object)(object)((Component)player.GetAttachPoint()).GetComponentInParent<Ship>() == (Object)(object)ship)) { return true; } RaycastHit? val = null; RaycastHit[] array = Physics.RaycastAll(((Component)player).transform.position + Vector3.up * 0.3f, Vector3.down, 1.5f, -5, (QueryTriggerInteraction)1); RaycastHit value2; for (int i = 0; i < array.Length; i++) { RaycastHit value = array[i]; if ((Object)(object)((Component)((RaycastHit)(ref value)).collider).GetComponentInParent<Player>() == (Object)(object)player) { continue; } if (val.HasValue) { float distance = ((RaycastHit)(ref value)).distance; value2 = val.Value; if (!(distance < ((RaycastHit)(ref value2)).distance)) { continue; } } val = value; } if (val.HasValue) { value2 = val.Value; return (Object)(object)((Component)((RaycastHit)(ref value2)).collider).GetComponentInParent<Ship>() == (Object)(object)ship; } return false; } public static float ObservedSpeed(Ship ship) { //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_0047: Unknown result type (might be due to invalid IL or missing references) if (ship.IsOwner()) { return ship.GetSpeed(); } ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return 0f; } return Vector3.Dot(component.GetZDO().GetVec3(ZDOVars.s_velHash, Vector3.zero), ((Component)ship).transform.forward); } public static float RowingForce(Ship ship) { return ship.m_backwardForce * (ship.IsOwner() ? Balance.SailForce(CaptainLevel(ship), instance.MaximumSpeedBonus.Value) : 1f); } } }