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 Glider Plus Valheim Glider Addon v1.0.0
BepInEx/plugins/WDIENAT-Glider_Plus_Valheim_Glider_Addon/GliderPlus.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using IBelieveICanFly.Patches; using IBelieveICanFly.Registration; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("GliderSkill.Tests")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WDIENAT")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A trainable Gliding skill for Yggdrah's ValheimGlider.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Glider-Plus Valheim-Glider Addon")] [assembly: AssemblyTitle("GliderPlus")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WDIENAT.GliderSkill { internal static class CallSiteRewriter { internal static MethodInfo StaticMethod(Type type, string name) { return type.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } internal static IEnumerable<CodeInstruction> InsertModifier(IEnumerable<CodeInstruction> instructions, MethodInfo getter, MethodInfo modifier) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown if (getter == null || modifier == null) { throw new MissingMethodException("A glider integration method was not found."); } List<CodeInstruction> list = instructions.ToList(); int num = list.Count((CodeInstruction code) => CodeInstructionExtensions.Calls(code, getter)); if (num != 1) { throw new InvalidOperationException($"Expected exactly one call to {getter.Name}; found {num}. Unsupported ValheimGlider implementation."); } List<CodeInstruction> list2 = new List<CodeInstruction>(list.Count + 2); foreach (CodeInstruction item in list) { list2.Add(item); if (!CodeInstructionExtensions.Calls(item, getter)) { continue; } list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)modifier); foreach (ExceptionBlock item2 in item.blocks.Where((ExceptionBlock block) => (int)block.blockType == 5).ToList()) { item.blocks.Remove(item2); val.blocks.Add(item2); } list2.Add(val); } return list2; } } [HarmonyPatch(typeof(GliderSystem), "ConsumeGliderStamina")] internal static class StaminaPatch { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return CallSiteRewriter.InsertModifier(instructions, CallSiteRewriter.StaticMethod(typeof(Config), "GetGliderStaminaDrainPerSecond"), CallSiteRewriter.StaticMethod(typeof(Plugin), "AdjustStaminaDrain")); } } [HarmonyPatch(typeof(GliderSystem), "ApplyVisualTilt")] internal static class ControlPatch { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return CallSiteRewriter.InsertModifier(CallSiteRewriter.InsertModifier(CallSiteRewriter.InsertModifier(instructions, CallSiteRewriter.StaticMethod(typeof(Config), "GetWingsAirTurnSpeed"), CallSiteRewriter.StaticMethod(typeof(Plugin), "AdjustTurnSpeed")), CallSiteRewriter.StaticMethod(typeof(Config), "GetWingsTiltPitchSmoothTime"), CallSiteRewriter.StaticMethod(typeof(Plugin), "AdjustSmoothTime")), CallSiteRewriter.StaticMethod(typeof(Config), "GetWingsTiltRollSmoothTime"), CallSiteRewriter.StaticMethod(typeof(Plugin), "AdjustSmoothTime")); } } [HarmonyPatch(typeof(GliderSystem), "ApplyGlidingPhysics")] internal static class ExperiencePatch { [HarmonyPostfix] private static void Postfix(Player player) { Plugin.AwardFlightExperience(player); } } [BepInPlugin("WDIENAT.GliderSkill", "Glider-Plus Valheim-Glider Addon", "1.0.0")] [BepInDependency("Yggdrah.ValheimGliders", "1.0.4")] [BepInDependency("com.jotunn.jotunn", "2.30.1")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "WDIENAT.GliderSkill"; public const string PluginName = "Glider-Plus Valheim-Glider Addon"; public const string PluginVersion = "1.0.0"; public const string Author = "WDIENAT"; public const string SkillIdentifier = "WDIENAT.GliderSkill.Gliding"; internal static SkillType GlidingSkill; internal static ConfigEntry<float> ExperiencePerSecond; internal static ConfigEntry<float> ControlBonusPercent; internal static ConfigEntry<float> StaminaReductionPercent; private static readonly ConditionalWeakTable<Player, FlightExperience> Progress = new ConditionalWeakTable<Player, FlightExperience>(); private Harmony harmony; private Sprite skillIcon; private Texture2D skillTexture; private void Awake() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00fe: Expected O, but got Unknown //IL_00f9: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected I4, but got Unknown ExperiencePerSecond = Bind("Experience", "ExperiencePerSecond", 1f, 0f, 10f, "Base skill experience per second of active gliding. 0 disables experience gain. Rested and world skill gain modifiers still apply."); ControlBonusPercent = Bind("Bonuses", "ControlBonusAtLevel100", 50f, 0f, 200f, "Percent increase to turning responsiveness at level 100. Pitch and bank smoothing times are divided by the same multiplier. Scales linearly from level 0."); StaminaReductionPercent = Bind("Bonuses", "StaminaReductionAtLevel100", 30f, 0f, 90f, "Percent reduction of gliding stamina drain at level 100. Only applies if ValheimGlider enables stamina drain. Scales linearly from level 0."); harmony = new Harmony("WDIENAT.GliderSkill"); try { harmony.PatchAll(typeof(Plugin).Assembly); AddTranslations(); if (!Application.isBatchMode) { LoadSkillIcon(); } GlidingSkill = SkillManager.Instance.AddSkill(new SkillConfig { Identifier = "WDIENAT.GliderSkill.Gliding", Name = "$skill_wdienat_gliding", Description = "$skill_wdienat_gliding_description", IncreaseStep = 1f, Icon = skillIcon }); if ((int)GlidingSkill == 0) { throw new InvalidOperationException("Skill registration failed."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} by {2} loaded. Gliding skill ID: {3}.", "Glider-Plus Valheim-Glider Addon", "1.0.0", "WDIENAT", (int)GlidingSkill)); } catch (Exception arg) { harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0} could not initialize; its patches were removed. {1}", "Glider-Plus Valheim-Glider Addon", arg)); throw; } } private ConfigEntry<float> Bind(string section, string key, float value, float min, float max, string description) { //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_0033: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, value, new ConfigDescription(description + " [Synced with server]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); } private static void AddTranslations() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["skill_wdienat_gliding"] = "Gliding", ["skill_wdienat_gliding_description"] = "Practice by flying with an open glider. Higher skill improves steering, pitch and bank response and reduces stamina drain when glider stamina is enabled." }); text = "Russian"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["skill_wdienat_gliding"] = "Планирование", ["skill_wdienat_gliding_description"] = "Развивается при полёте с раскрытым глайдером. Улучшает повороты, реакцию на наклон и крен, а также снижает расход выносливости, если он включён у глайдера." }); } private void LoadSkillIcon() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_00a8: 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) using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WDIENAT.GliderSkill.skill.png")) { if (stream == null) { throw new InvalidOperationException("Embedded skill icon is missing."); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); skillTexture = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(skillTexture, memoryStream.ToArray(), true)) { throw new InvalidOperationException("Embedded skill icon is invalid."); } } ((Object)skillTexture).name = "WDIENAT_GlidingSkill"; skillIcon = Sprite.Create(skillTexture, new Rect(0f, 0f, (float)((Texture)skillTexture).width, (float)((Texture)skillTexture).height), new Vector2(0.5f, 0.5f)); } internal static bool IsLocalFlight(Player player) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer && (int)GlidingSkill != 0 && GliderSystem.IsCurrentlyGliding() && GliderSystem.GetCurrentWingsIndex() > 0 && !((Character)player).IsDead() && !((Character)player).IsOnGround() && !((Character)player).InWater() && !((Character)player).IsAttached() && !((Character)player).IsTeleporting()) { return !((Character)player).IsDebugFlying(); } return false; } private static float Factor(Player player) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Skills skills = ((Character)player).GetSkills(); if (!((Object)(object)skills == (Object)null)) { return skills.GetSkillFactor(GlidingSkill); } return 0f; } internal static float AdjustStaminaDrain(float original, Player player) { if (!IsLocalFlight(player)) { return original; } return original * SkillBalance.StaminaMultiplier(Factor(player), StaminaReductionPercent.Value, Config.GetGliderStaminaEnabled()); } internal static float AdjustTurnSpeed(float original, Player player) { if (!IsLocalFlight(player)) { return original; } return original * SkillBalance.ControlMultiplier(Factor(player), ControlBonusPercent.Value); } internal static float AdjustSmoothTime(float original, Player player) { if (!IsLocalFlight(player)) { return original; } return original / SkillBalance.ControlMultiplier(Factor(player), ControlBonusPercent.Value); } internal static void AwardFlightExperience(Player player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } int num; if (IsLocalFlight(player)) { Vector3 velocity = ((Character)player).GetVelocity(); num = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num = 0; } bool eligible = (byte)num != 0; int num2 = Progress.GetValue(player, (Player _) => new FlightExperience()).Sample(Time.frameCount, Time.deltaTime, eligible); float num3 = SkillBalance.FiniteClamp(ExperiencePerSecond.Value, 0f, 10f, 1f); for (int num4 = 0; num4 < num2; num4++) { if (!(num3 > 0f)) { break; } ((Character)player).RaiseSkill(GlidingSkill, num3); } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } if ((Object)(object)skillIcon != (Object)null) { Object.Destroy((Object)(object)skillIcon); } if ((Object)(object)skillTexture != (Object)null) { Object.Destroy((Object)(object)skillTexture); } } } internal static class SkillBalance { internal const float DefaultExperiencePerSecond = 1f; internal const float DefaultControlBonusPercent = 50f; internal const float DefaultStaminaReductionPercent = 30f; internal static float FiniteClamp(float value, float min, float max, float fallback) { if (float.IsNaN(value) || float.IsInfinity(value)) { return fallback; } return Math.Max(min, Math.Min(max, value)); } internal static float ControlMultiplier(float skillFactor, float bonusPercent) { return 1f + FiniteClamp(skillFactor, 0f, 1f, 0f) * FiniteClamp(bonusPercent, 0f, 200f, 50f) / 100f; } internal static float StaminaMultiplier(float skillFactor, float reductionPercent, bool staminaEnabled) { if (!staminaEnabled) { return 1f; } return 1f - FiniteClamp(skillFactor, 0f, 1f, 0f) * FiniteClamp(reductionPercent, 0f, 90f, 30f) / 100f; } } internal sealed class FlightExperience { private double seconds; private int lastFrame = -1; internal int Sample(int frame, float deltaTime, bool eligible) { if (frame == lastFrame) { return 0; } lastFrame = frame; if (!eligible || deltaTime <= 0f || deltaTime > 0.5f || float.IsNaN(deltaTime) || float.IsInfinity(deltaTime)) { return 0; } seconds += deltaTime; int num = (int)Math.Floor(seconds + 1E-06); if (num > 0) { seconds = Math.Max(0.0, seconds - (double)num); } return num; } } }