using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using DiskCardGame; using HarmonyLib; using InscryptionAPI.Card; using InscryptionAPI.Helpers; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OldSa_Strafe Strike_sigil")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OldSa_Strafe Strike_sigil")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a396b6fd-2b3b-4ced-aca0-69ad30118ef9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace OLD_SA.StrafeStrike; [BepInPlugin("OLD_SA.StrafeStrike", "OLD SA Strafe Strike", "1.0.0")] public class Plugin : BaseUnityPlugin { private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("OLD_SA.StrafeStrike"); StrafeStrikeAPI.Init(); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"OLD SA Strafe Strike Loaded"); } } public static class StrafeStrikeAPI { public static FullAbility ability; public static void Init() { AbilityInfo val = ScriptableObject.CreateInstance(); ((Object)val).name = "Strafe Strike"; val.rulebookName = "Strafe Strike"; val.metaCategories = new List { (AbilityMetaCategory)0, (AbilityMetaCategory)1 }; val.powerLevel = 4; val.opponentUsable = true; val.canStack = false; Texture imageAsTexture = (Texture)(object)TextureHelper.GetImageAsTexture("OldSa_Strafe_Strike.png", (FilterMode)0); FieldInfo field = typeof(AbilityInfo).GetField("rulebookDescription", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(val, "After [creature] moves, it attacks."); } ability = AbilityManager.Add("OLD_SA", val, typeof(StrafeStrikeBehaviour), imageAsTexture); } } public class StrafeStrikeBehaviour : AbilityBehaviour { private CardSlot lastSlot; public override Ability Ability => StrafeStrikeAPI.ability.Id; public override bool RespondsToResolveOnBoard() { return (Object)(object)((AbilityBehaviour)this).Card != (Object)null && !((AbilityBehaviour)this).Card.Dead && (Object)(object)((AbilityBehaviour)this).Card.Slot != (Object)null; } public override IEnumerator OnResolveOnBoard() { if (!((Object)(object)((AbilityBehaviour)this).Card == (Object)null) && !((AbilityBehaviour)this).Card.Dead && !((Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)null)) { lastSlot = ((AbilityBehaviour)this).Card.Slot; } yield break; } public override bool RespondsToOtherCardAssignedToSlot(PlayableCard otherCard) { if ((Object)(object)((AbilityBehaviour)this).Card == (Object)null || ((AbilityBehaviour)this).Card.Dead) { return false; } if ((Object)(object)otherCard == (Object)null || otherCard.Dead) { return false; } if ((Object)(object)otherCard != (Object)(object)((AbilityBehaviour)this).Card) { return false; } if ((Object)(object)lastSlot == (Object)null) { return false; } if ((Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)null || (Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)(object)lastSlot) { return false; } return true; } public override IEnumerator OnOtherCardAssignedToSlot(PlayableCard otherCard) { if ((Object)(object)((AbilityBehaviour)this).Card == (Object)null || ((AbilityBehaviour)this).Card.Dead || (Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)null || (Object)(object)otherCard == (Object)null || (Object)(object)otherCard != (Object)(object)((AbilityBehaviour)this).Card || otherCard.Dead) { yield break; } CardSlot attackingSlot = ((AbilityBehaviour)this).Card.Slot; if ((Object)(object)lastSlot == (Object)null || (Object)(object)attackingSlot == (Object)(object)lastSlot) { yield break; } lastSlot = attackingSlot; yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); if ((Object)(object)((AbilityBehaviour)this).Card == (Object)null || ((AbilityBehaviour)this).Card.Dead || (Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)null) { yield break; } attackingSlot = ((AbilityBehaviour)this).Card.Slot; CardSlot opposingSlot = attackingSlot.opposingSlot; if ((Object)(object)opposingSlot == (Object)null) { yield break; } CombatPhaseManager combat = Singleton.Instance; if (!((Object)(object)combat == (Object)null)) { int damageBefore = combat.DamageDealtThisPhase; yield return combat.SlotAttackSlot(attackingSlot, opposingSlot, 0f); int damageAfter = combat.DamageDealtThisPhase; int damage = damageAfter - damageBefore; if (damage <= 0) { yield return ((AbilityBehaviour)this).LearnAbility(0.25f); yield break; } yield return ResolveDamage(combat, damage, attackingSlot.IsPlayerSlot); yield return ((AbilityBehaviour)this).LearnAbility(0.25f); } } private IEnumerator ResolveDamage(CombatPhaseManager combat, int damage, bool playerIsAttacker) { if (!((Object)(object)combat == (Object)null) && damage > 0) { yield return (object)new WaitForSeconds(0.4f); int excessDamage = 0; if (playerIsAttacker) { excessDamage = Singleton.Instance.Balance + damage - 5; excessDamage = Mathf.Max(0, excessDamage); } int damageToScales = damage - excessDamage; yield return Singleton.Instance.ShowDamageSequence(damageToScales, damageToScales, !playerIsAttacker, 0f, (GameObject)null, 0f, true); if (excessDamage > 0 && playerIsAttacker && (Object)(object)Singleton.Instance != (Object)null && (Object)(object)Singleton.Instance.Opponent != (Object)null && Singleton.Instance.Opponent.NumLives == 1 && Singleton.Instance.Opponent.GiveCurrencyOnDefeat) { yield return Singleton.Instance.Opponent.TryRevokeSurrender(); RunState run = RunState.Run; run.currency += excessDamage; yield return VisualizeExcessLethalDamage(excessDamage); } SetDamageDealtThisPhase(combat, combat.DamageDealtThisPhase - damage); } } private static void SetDamageDealtThisPhase(CombatPhaseManager combat, int value) { if ((Object)(object)combat == (Object)null) { return; } PropertyInfo property = typeof(CombatPhaseManager).GetProperty("DamageDealtThisPhase", BindingFlags.Instance | BindingFlags.Public); if (!(property == null)) { MethodInfo setMethod = property.GetSetMethod(nonPublic: true); if (!(setMethod == null)) { setMethod.Invoke(combat, new object[1] { Mathf.Max(0, value) }); } } } private IEnumerator VisualizeExcessLethalDamage(int excessDamage) { if (excessDamage <= 0) { yield break; } MethodInfo method = typeof(CombatPhaseManager).GetMethod("VisualizeExcessLethalDamage", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { yield break; } object result = method.Invoke(Singleton.Instance, new object[2] { excessDamage, null }); if (result is IEnumerator sequence) { while (sequence.MoveNext()) { yield return sequence.Current; } } } }