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 BetterReaper v0.1.1
BetterReaper.dll
Decompiled 8 months agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using HutongGames.PlayMaker; using Microsoft.CodeAnalysis; 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("BetterReaper")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1+180e03c30602f04948a13c924545018deb3cb0fa")] [assembly: AssemblyProduct("BetterReaper")] [assembly: AssemblyTitle("BetterReaper")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Clazex/Silksong.BetterReaper")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BetterReaper { [BepInPlugin("dev.clazex.betterreaper", "BetterReaper", "0.1.1")] public sealed class BetterReaperPlugin : BaseUnityPlugin { public const string Id = "dev.clazex.betterreaper"; public static BetterReaperPlugin Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; private static Harmony Harmony { get; } = new Harmony("dev.clazex.betterreaper"); public static string Name => "BetterReaper"; public static string Version => "0.1.1"; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Harmony.PatchAll(typeof(Patches)); Logger.LogInfo((object)("Plugin " + Name + " (dev.clazex.betterreaper) v" + Version + " is loaded!")); } private void OnDestroy() { Logger.LogWarning((object)"Unload called in release build"); Harmony.UnpatchSelf(); Logger.LogInfo((object)("Plugin " + Name + " has unloaded!")); } internal static void ReaperReward(HeroController hc) { Logger.LogDebug((object)"Giving reaper mode finishing reward"); if (hc.playerData.health < hc.playerData.CurrentMaxHealth) { hc.AddHealth(1); } else { hc.AddSilk(3, true); } } } internal static class Constants { public const float STUN_DAMAGE_MULT = 1.5f; public const float STUN_DAMAGE_MULT_HEAVY = 1.75f; public const int SILK_PER_HEALTH = 3; public const float GREAT_SLASH_SCALE = 1.45f; public const float BUNDLE_PROB_1 = 0.25f; public const float BUNDLE_PROB_2 = 0.5f; public const float BUNDLE_PROB_3 = 0.25f; public const float FLING_SPEED_MIN = 18.75f; public const float FLING_SPEED_MAX = 37.5f; } internal sealed class ListenForBindComplete : FsmStateAction { private static readonly HashSet<ListenForBindComplete> instances = new HashSet<ListenForBindComplete>(); internal FsmEvent fsmEvent; public ListenForBindComplete(FsmEvent fsmEvent) { this.fsmEvent = fsmEvent; ((FsmStateAction)this)..ctor(); } public override void OnEnter() { ((FsmStateAction)this).BlocksFinish = false; instances.Add(this); } public override void OnExit() { instances.Remove(this); } private void OnNotify() { ((FsmStateAction)this).Fsm.Event(fsmEvent); ((FsmStateAction)this).Finish(); } internal static void NotifyAll() { BetterReaperPlugin.Logger.LogDebug((object)"Notifying bind complete"); ListenForBindComplete[] array = instances.ToArray(); for (int i = 0; i < array.Length; i++) { array[i].OnNotify(); } } } internal static class Patches { [HarmonyPatch(typeof(HeroController), "Start")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Setup(HeroController __instance) { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) BetterReaperPlugin.Logger.LogDebug((object)"Setting up hero"); HeroControllerConfig config = ToolItemManager.GetCrestByName("Reaper").HeroConfig; ConfigGroup val = __instance.configs.First((ConfigGroup i) => (Object)(object)i.Config == (Object)(object)config); DamageEnemies normalSlashDamager = val.NormalSlashDamager; normalSlashDamager.stunDamage *= 1.5f; DamageEnemies alternateSlashDamager = val.AlternateSlashDamager; alternateSlashDamager.stunDamage *= 1.5f; DamageEnemies upSlashDamager = val.UpSlashDamager; upSlashDamager.stunDamage *= 1.5f; DamageEnemies wallSlashDamager = val.WallSlashDamager; wallSlashDamager.stunDamage *= 1.5f; Transform obj = __instance.transform.Find("Attacks/Scythe"); ((Component)obj.Find("DownSlash New")).GetComponent<DamageEnemies>(); DamageEnemies wallSlashDamager2 = val.WallSlashDamager; wallSlashDamager2.stunDamage *= 1.75f; ((Component)obj.Find("DashUpper Slash")).GetComponent<DamageEnemies>(); DamageEnemies component = ((Component)obj.Find("DashUpper Slash/Extra Damager")).GetComponent<DamageEnemies>(); component.stunDamage *= 1.75f; EnemyDamagerGroup component2 = ((Component)__instance.transform.Find("Attacks/Charge Slash Scythe")).GetComponent<EnemyDamagerGroup>(); DamageEnemies[] damagers = component2.damagers; foreach (DamageEnemies obj2 in damagers) { obj2.stunDamage *= 1.75f; } Extensions.SetScale2D(((Component)component2).transform, Vector2.one * 1.45f); ProbabilityInt[] reaperBundleDrops = __instance.reaperBundleDrops; ((ProbabilityBase<int>)(object)reaperBundleDrops[0]).Probability = 0.25f; ((ProbabilityBase<int>)(object)reaperBundleDrops[1]).Probability = 0.5f; ((ProbabilityBase<int>)(object)reaperBundleDrops[2]).Probability = 0.25f; } [HarmonyPatch(typeof(ObjectPool), "AddSpawnedObject")] [HarmonyWrapSafe] [HarmonyPostfix] private static void AutoCollectSilkOrbs(GameObject obj, GameObject prefab) { if (!(((Object)prefab).name != "Reaper Silk Bundle") && !((Object)(object)obj.GetComponent<SilkOrbEditMarker>() != (Object)null)) { BetterReaperPlugin.Logger.LogDebug((object)"Modifying Reaper Silk Bundle"); obj.AddComponent<SilkOrbEditMarker>(); Fsm fsm = FSMUtility.LocateMyFSM(obj, "Control").Fsm; fsm.GetState("Get Silk").Actions[2].Enabled = false; FsmState state = fsm.GetState("Collectable"); FsmTransition obj2 = state.Transitions.First((FsmTransition i) => i.EventName == "DISAPPEAR"); obj2.ToFsmState = fsm.GetState("Collect"); obj2.toState = obj2.toFsmState.Name; FsmStateAction[] actions = state.Actions; int num = 0; FsmStateAction[] array = (FsmStateAction[])(object)new FsmStateAction[1 + actions.Length]; ReadOnlySpan<FsmStateAction> readOnlySpan = new ReadOnlySpan<FsmStateAction>(actions); readOnlySpan.CopyTo(new Span<FsmStateAction>(array).Slice(num, readOnlySpan.Length)); num += readOnlySpan.Length; array[num] = (FsmStateAction)(object)new ListenForBindComplete(FsmEvent.GetFsmEvent("REAP")); state.Actions = array; } } [HarmonyPatch(typeof(HeroController), "ResetReaperCrestState")] [HarmonyWrapSafe] [HarmonyPrefix] private static void ReaperExitAward(HeroController __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ReaperCrestStateInfo reaperState = __instance.reaperState; if (reaperState.IsInReaperMode && reaperState.ReaperModeDurationLeft <= 0f) { BetterReaperPlugin.ReaperReward(__instance); } } [HarmonyPatch(typeof(HeroController), "BindCompleted")] [HarmonyWrapSafe] [HarmonyPrefix] private static void ReaperRestartAward(HeroController __instance) { ListenForBindComplete.NotifyAll(); if (__instance.reaperState.IsInReaperMode) { BetterReaperPlugin.ReaperReward(__instance); } } [HarmonyPatch(typeof(HealthManager), "TakeDamage")] [HarmonyWrapSafe] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> ChangeFlingSpeed(IEnumerable<CodeInstruction> insts) { //IL_0002: 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_002b: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown return new CodeMatcher(insts, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)25f, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/), (string)null) }).SetOperandAndAdvance((object)18.75f).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)50f, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/), (string)null) }) .SetOperandAndAdvance((object)37.5f) .InstructionEnumeration(); } [HarmonyPatch(typeof(HeroController), "TakeDamage")] [HarmonyWrapSafe] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> RemoveReaperReset(IEnumerable<CodeInstruction> insts, ILGenerator generator) { //IL_0002: 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_0022: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown return new CodeMatcher(insts, generator).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)(MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (string)null) }).RemoveInstructions(2).InstructionEnumeration(); } [HarmonyPatch(typeof(PlayerData), "TakeHealth")] [HarmonyWrapSafe] [HarmonyPrefix] private static void ResetReaperOnActualDamage(PlayerData __instance, ref int amount) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) HeroController instance = HeroController.instance; if (instance.ReaperState.IsInReaperMode) { int num = Math.Min(__instance.silk / 3, amount); instance.TakeSilk(num * 3); amount -= num; BetterReaperPlugin.Logger.LogDebug((object)$"Reaper mode reducing damage by {num} to {amount}"); if (amount > 0) { BetterReaperPlugin.Logger.LogDebug((object)"Resetting reaper mode"); instance.ResetReaperCrestState(); } else { BetterReaperPlugin.Logger.LogDebug((object)"Exempted reaper mode reset"); } } } } internal sealed class SilkOrbEditMarker : MonoBehaviour { } } internal class BetterReaper_ProcessedByFody { internal const string FodyVersion = "6.9.3.0"; internal const string InfoOf = "2.2.0.0"; }