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 FalseSonMod v1.1.0
FalseSonMod.dll
Decompiled 11 hours agousing System; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using EntityStates; using EntityStates.FalseSon; using HarmonyLib; using Microsoft.CodeAnalysis; using R2API; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FalseSonMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("FalseSonMod")] [assembly: AssemblyTitle("FalseSonMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [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 FalseSonMod { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.blue.falsesonmod", "False Son Buffs", "1.1.0")] public class FalseSonModPlugin : BaseUnityPlugin { public const string PluginGUID = "com.blue.falsesonmod"; public const string PluginName = "False Son Buffs"; public const string PluginVersion = "1.1.0"; public static ConfigEntry<float> HealthMultiplier; public static ConfigEntry<float> DamageMultiplier; public static ConfigEntry<float> ArmorBonus; public static ConfigEntry<float> MoveSpeedMultiplier; public static ConfigEntry<float> RegenMultiplier; public static ConfigEntry<float> GuaranteedAttackSpeedMultiplier; public static ConfigEntry<float> GuaranteedArmorFromSpikes; public static ConfigEntry<float> GuaranteedRegenFromSpentSpikes; public static ConfigEntry<float> ExtraJumpPowerOnSpecial; public static ConfigEntry<float> ExtraJumpPowerDurationSeconds; public static ConfigEntry<float> ChargeSlamWindupSeconds; public static ConfigEntry<float> ChargeMoveSpeedCoefficient; public static ConfigEntry<float> FallDamageBonusPerMeter; public static ConfigEntry<float> FallSizeBonusPerMeter; private void Awake() { //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) HealthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Buffs", "HealthMultiplier", 1.2f, "Max health multiplier."); DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Buffs", "DamageMultiplier", 1.25f, "Base damage multiplier."); ArmorBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Buffs", "ArmorBonus", 15f, "Flat armor added to his base 20."); MoveSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Buffs", "MoveSpeedMultiplier", 1.1f, "Move speed multiplier."); RegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Buffs", "RegenMultiplier", 1.5f, "HP regen multiplier."); GuaranteedAttackSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("LunarTampering", "GuaranteedAttackSpeedMultiplier", 1.15f, "Unconditional attack speed bonus standing in for the 'held spike' buff."); GuaranteedArmorFromSpikes = ((BaseUnityPlugin)this).Config.Bind<float>("LunarTampering", "GuaranteedArmorFromSpikes", 10f, "Unconditional flat armor standing in for the 'held spike' buff."); GuaranteedRegenFromSpentSpikes = ((BaseUnityPlugin)this).Config.Bind<float>("LunarTampering", "GuaranteedRegenFromSpentSpikes", 0.75f, "Unconditional flat regen standing in for the 'spent spike' buff."); ExtraJumpPowerOnSpecial = ((BaseUnityPlugin)this).Config.Bind<float>("Mobility", "ExtraJumpPowerMultiplier", 1.5f, "Jump power multiplier while the buff from using Special is active."); ExtraJumpPowerDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Mobility", "ExtraJumpPowerDurationSeconds", 2f, "How long the extra jump power lasts after using Special."); ChargeSlamWindupSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("ChargedSlam", "WindupSeconds", 0.05f, "How long the Charged Slam hold takes before it fires. Near-zero, not literally 0, to avoid input-frame edge cases. Also shrinks the charge-up animation to match."); ChargeMoveSpeedCoefficient = ((BaseUnityPlugin)this).Config.Bind<float>("ChargedSlam", "MoveSpeedCoefficientWhileCharging", 1.4f, "Movement speed multiplier while charging the slam (vanilla slows you down here). 1.0 = normal walk speed, >1 = faster than walking, roughly sprint-equivalent."); FallDamageBonusPerMeter = ((BaseUnityPlugin)this).Config.Bind<float>("ChargedSlam", "FallDamageBonusPerMeter", 0.03f, "Extra damage multiplier per meter fallen since last touching ground (Headstompers-style). Uncapped."); FallSizeBonusPerMeter = ((BaseUnityPlugin)this).Config.Bind<float>("ChargedSlam", "FallSizeBonusPerMeter", 0.02f, "Extra size multiplier (blast radius/VFX/force) per meter fallen. Uncapped."); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(ApplyStatBuffs); new Harmony("com.blue.falsesonmod").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"False Son Buffs v1.1.0 loaded."); } private static bool IsFalseSon(CharacterBody body) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)body == (Object)null || (int)body.bodyIndex < 0) { return false; } string bodyName = BodyCatalog.GetBodyName(body.bodyIndex); if (!string.IsNullOrEmpty(bodyName)) { return bodyName.Contains("FalseSon"); } return false; } private void ApplyStatBuffs(CharacterBody body, StatHookEventArgs args) { if (IsFalseSon(body)) { args.healthMultAdd += HealthMultiplier.Value - 1f; args.damageMultAdd += DamageMultiplier.Value - 1f; args.armorAdd += ArmorBonus.Value; args.moveSpeedMultAdd += MoveSpeedMultiplier.Value - 1f; args.regenMultAdd += RegenMultiplier.Value - 1f; args.attackSpeedMultAdd += GuaranteedAttackSpeedMultiplier.Value - 1f; args.armorAdd += GuaranteedArmorFromSpikes.Value; args.baseRegenAdd += GuaranteedRegenFromSpentSpikes.Value; } } } [HarmonyPatch(typeof(ClubSwing3), "OnEnter")] public static class ClubSwing3ChargePatch { private static readonly Type StateType = typeof(ClubSwing3); private static readonly FieldInfo BaseChargeDurationField = AccessTools.Field(StateType, "baseChargeDuration"); private static readonly FieldInfo WalkSpeedCoefficientField = AccessTools.Field(StateType, "walkSpeedCoefficient"); private static void Prefix(ClubSwing3 __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) CharacterBody characterBody = ((EntityState)__instance).characterBody; if (!((Object)(object)characterBody == (Object)null)) { string bodyName = BodyCatalog.GetBodyName(characterBody.bodyIndex); if (!string.IsNullOrEmpty(bodyName) && bodyName.Contains("FalseSon")) { BaseChargeDurationField?.SetValue(__instance, FalseSonModPlugin.ChargeSlamWindupSeconds.Value); WalkSpeedCoefficientField?.SetValue(__instance, FalseSonModPlugin.ChargeMoveSpeedCoefficient.Value); Debug.Log((object)("[FalseSonMod] ClubSwing3 (charge hold) tweaked: chargeDuration=" + $"{FalseSonModPlugin.ChargeSlamWindupSeconds.Value}, walkSpeedCoeff=" + $"{FalseSonModPlugin.ChargeMoveSpeedCoefficient.Value}")); } } } } [HarmonyPatch(typeof(ChargedClubSwing), "OnEnter")] public static class ChargedClubSwingTweaksPatch { private static readonly Type StateType = typeof(ChargedClubSwing); private static readonly FieldInfo BaseDurationField = AccessTools.Field(StateType, "baseDuration"); private static readonly FieldInfo BaseMinimumDurationField = AccessTools.Field(StateType, "baseMinimumDuration"); private static readonly FieldInfo PlayerWalkSpeedCoefficientField = AccessTools.Field(StateType, "playerWalkSpeedCoefficient"); private static readonly FieldInfo BlastRadiusField = AccessTools.Field(StateType, "blastRadius"); private static readonly FieldInfo BlastVfxScaleField = AccessTools.Field(StateType, "blastVFXScaleMultiplier"); private static readonly FieldInfo BlastDamageCoefficientField = AccessTools.Field(StateType, "blastDamageCoefficient"); private static readonly FieldInfo BlastForceField = AccessTools.Field(StateType, "blastForce"); private static void Prefix(ChargedClubSwing __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) CharacterBody characterBody = ((EntityState)__instance).characterBody; if ((Object)(object)characterBody == (Object)null) { return; } string bodyName = BodyCatalog.GetBodyName(characterBody.bodyIndex); if (!string.IsNullOrEmpty(bodyName) && bodyName.Contains("FalseSon")) { float value = FalseSonModPlugin.ChargeSlamWindupSeconds.Value; BaseDurationField?.SetValue(__instance, value); BaseMinimumDurationField?.SetValue(__instance, value); PlayerWalkSpeedCoefficientField?.SetValue(__instance, FalseSonModPlugin.ChargeMoveSpeedCoefficient.Value); FallHeightTracker fallHeightTracker = ((Component)characterBody).GetComponent<FallHeightTracker>(); if ((Object)(object)fallHeightTracker == (Object)null) { fallHeightTracker = ((Component)characterBody).gameObject.AddComponent<FallHeightTracker>(); } float currentFallDistance = fallHeightTracker.CurrentFallDistance; float num = currentFallDistance * FalseSonModPlugin.FallDamageBonusPerMeter.Value; float num2 = currentFallDistance * FalseSonModPlugin.FallSizeBonusPerMeter.Value; if (BlastRadiusField != null) { BlastRadiusField.SetValue(__instance, (float)BlastRadiusField.GetValue(__instance) * (1f + num2)); } if (BlastVfxScaleField != null) { BlastVfxScaleField.SetValue(__instance, (float)BlastVfxScaleField.GetValue(__instance) * (1f + num2)); } if (BlastForceField != null) { BlastForceField.SetValue(__instance, (float)BlastForceField.GetValue(__instance) * (1f + num2)); } if (BlastDamageCoefficientField != null) { BlastDamageCoefficientField.SetValue(__instance, (float)BlastDamageCoefficientField.GetValue(__instance) * (1f + num)); } Debug.Log((object)($"[FalseSonMod] ChargedClubSwing (impact) tweaked: fallDistance={currentFallDistance:F1}, " + $"damageBonus={num:F2}, sizeBonus={num2:F2}")); } } } [HarmonyPatch(typeof(GenericSkill), "OnExecute")] public static class SpecialJumpBoostPatch { private static void Postfix(GenericSkill __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) CharacterBody characterBody = __instance.characterBody; if ((Object)(object)characterBody == (Object)null) { return; } string bodyName = BodyCatalog.GetBodyName(characterBody.bodyIndex); if (string.IsNullOrEmpty(bodyName) || !bodyName.Contains("FalseSon")) { return; } SkillLocator component = ((Component)characterBody).GetComponent<SkillLocator>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)__instance != (Object)(object)component.special)) { TemporaryJumpPowerBoost temporaryJumpPowerBoost = ((Component)characterBody).GetComponent<TemporaryJumpPowerBoost>(); if ((Object)(object)temporaryJumpPowerBoost == (Object)null) { temporaryJumpPowerBoost = ((Component)characterBody).gameObject.AddComponent<TemporaryJumpPowerBoost>(); } temporaryJumpPowerBoost.Refresh(FalseSonModPlugin.ExtraJumpPowerOnSpecial.Value, FalseSonModPlugin.ExtraJumpPowerDurationSeconds.Value); } } } public class TemporaryJumpPowerBoost : MonoBehaviour { private static MemberInfo _cachedMember; private static object _cachedTarget; private static bool _searched; private CharacterMotor _motor; private CharacterBody _body; private float _baseValue; private float _timer; private void Awake() { _motor = ((Component)this).GetComponent<CharacterMotor>(); _body = ((Component)this).GetComponent<CharacterBody>(); } private static MemberInfo FindJumpPowerMember(out bool onMotor) { onMotor = true; Type[] array = new Type[2] { typeof(CharacterMotor), typeof(CharacterBody) }; foreach (Type type in array) { MemberInfo memberInfo = (from m in type.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where m is FieldInfo || m is PropertyInfo where m.Name.ToLowerInvariant().Contains("jump") && m.Name.ToLowerInvariant().Contains("power") select m).FirstOrDefault(); if (memberInfo != null) { onMotor = type == typeof(CharacterMotor); return memberInfo; } } return null; } private float GetValue(object target, MemberInfo member) { if (!(member is FieldInfo fieldInfo)) { return (float)((PropertyInfo)member).GetValue(target); } return (float)fieldInfo.GetValue(target); } private void SetValue(object target, MemberInfo member, float value) { if (member is FieldInfo fieldInfo) { fieldInfo.SetValue(target, value); } else { ((PropertyInfo)member).SetValue(target, value); } } public void Refresh(float multiplier, float duration) { if (!_searched) { _cachedMember = FindJumpPowerMember(out var onMotor); _cachedTarget = (onMotor ? ((object)_motor) : ((object)_body)); _searched = true; if (_cachedMember == null) { Debug.LogWarning((object)"[FalseSonMod] Could not find a jump-power member on CharacterMotor or CharacterBody. Jump boost on Special is disabled. Report this so the field name can be found another way."); } else { Debug.Log((object)("[FalseSonMod] Using jump-power member: " + _cachedMember.DeclaringType.Name + "." + _cachedMember.Name)); } } if (_cachedMember == null) { return; } object obj = ((_cachedMember.DeclaringType == typeof(CharacterMotor)) ? ((object)_motor) : ((object)_body)); if (obj != null) { if (_timer <= 0f) { _baseValue = GetValue(obj, _cachedMember); } _timer = duration; SetValue(obj, _cachedMember, _baseValue * multiplier); } } private void Update() { if (_timer <= 0f || _cachedMember == null) { return; } _timer -= Time.deltaTime; if (_timer <= 0f) { object obj = ((_cachedMember.DeclaringType == typeof(CharacterMotor)) ? ((object)_motor) : ((object)_body)); if (obj != null) { SetValue(obj, _cachedMember, _baseValue); } } } } [BepInPlugin("com.blue.falsesondiagnostics", "False Son Diagnostics", "1.0.0")] public class FalseSonDiagnosticsPlugin : BaseUnityPlugin { public const string PluginGUID = "com.blue.falsesondiagnostics"; public const string PluginName = "False Son Diagnostics"; public const string PluginVersion = "1.0.0"; private bool _dumpedTypes; private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"False Son Diagnostics loaded. F6 = type dump, F7 = live state dump."); } private void Update() { if (Input.GetKeyDown((KeyCode)287) && !_dumpedTypes) { DumpFalseSonTypes(); _dumpedTypes = true; } if (Input.GetKeyDown((KeyCode)288)) { DumpLocalBodyCurrentStates(); } } private void DumpFalseSonTypes() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"---- Scanning loaded assemblies for FalseSon-related EntityStates types ----"); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] types; try { types = assembly.GetTypes(); } catch { continue; } foreach (Type item in types.Where((Type t) => t.Namespace != null && t.Namespace.Contains("EntityStates") && (t.Namespace.Contains("FalseSon") || t.Name.Contains("FalseSon") || t.Name.Contains("Slam") || t.Name.Contains("Charge")))) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("TYPE: " + item.FullName)); FieldInfo[] fields = item.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(" field: " + fieldInfo.FieldType.Name + " " + fieldInfo.Name)); } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"---- Dump complete ----"); } private void DumpLocalBodyCurrentStates() { CharacterBody val = PlayerCharacterMasterController.instances?.Select(delegate(PlayerCharacterMasterController p) { CharacterMaster master = p.master; return (master == null) ? null : master.GetBody(); }).FirstOrDefault((Func<CharacterBody, bool>)((CharacterBody b) => (Object)(object)b != (Object)null && b.isPlayerControlled)); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"No local player body found (are you in a run?)."); return; } SkillLocator component = ((Component)val).GetComponent<SkillLocator>(); if ((Object)(object)component == (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"No SkillLocator on local body."); return; } LogSlot("Primary", component.primary); LogSlot("Secondary", component.secondary); LogSlot("Utility", component.utility); LogSlot("Special", component.special); void LogSlot(string slotName, GenericSkill skill) { EntityStateMachine val2 = (((Object)(object)skill != (Object)null) ? skill.stateMachine : null); string text = (((Object)(object)val2 != (Object)null && val2.state != null) ? ((object)val2.state).GetType().FullName : "(none)"); ((BaseUnityPlugin)this).Logger.LogInfo((object)(slotName + ": currentState = " + text)); } } } public class FallHeightTracker : MonoBehaviour { private CharacterMotor _motor; private float _peakY; private bool _wasGrounded = true; public float CurrentFallDistance { get; private set; } private void Awake() { _motor = ((Component)this).GetComponent<CharacterMotor>(); } private void FixedUpdate() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_motor == (Object)null) { return; } bool isGrounded = _motor.isGrounded; float y = ((Component)this).transform.position.y; if (!isGrounded) { if (_wasGrounded) { _peakY = y; } else { _peakY = Mathf.Max(_peakY, y); } CurrentFallDistance = Mathf.Max(0f, _peakY - y); } else if (!_wasGrounded) { CurrentFallDistance = Mathf.Max(0f, _peakY - y); } _wasGrounded = isGrounded; } } public static class PluginInfo { public const string PLUGIN_GUID = "FalseSonMod"; public const string PLUGIN_NAME = "FalseSonMod"; public const string PLUGIN_VERSION = "1.1.0"; } }