using System; 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 FUTSSNewCardsMod.Utils; using HarmonyLib; using InscryptionAPI.Ascension; using InscryptionAPI.Card; using InscryptionAPI.Guid; using InscryptionAPI.Helpers; using InscryptionAPI.Helpers.Extensions; using InscryptionAPI.Triggers; using Pixelplacement; 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("ForestUnderTheStarrySky")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ForestUnderTheStarrySky")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ce178e1a-8da7-40d5-a6ad-8af9c2f68bd8")] [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 FUTSSNewCardsMod.Utils { internal static class CombatBridge { private static MethodInfo _unlockAchievement; private static FieldInfo _weightPrefabField; private static MethodInfo _showCardBlocked; private static MethodInfo _preOverkillDamage; private static MethodInfo _postOverkillDamage; private static MethodInfo _visualizeClearSniper; static CombatBridge() { Type typeFromHandle = typeof(CombatPhaseManager); Type type = Type.GetType("DiskCardGame.AchievementManager, Assembly-CSharp"); if (type != null) { _unlockAchievement = AccessTools.Method(type, "Unlock", new Type[1] { typeof(Achievement) }, (Type[])null); } Type type2 = Type.GetType("DiskCardGame.CombatPhaseManager3D, Assembly-CSharp"); if (type2 != null) { _weightPrefabField = AccessTools.Field(type2, "weightPrefab"); } _unlockAchievement = AccessTools.Method(type, "Unlock", new Type[1] { typeof(Achievement) }, (Type[])null); _weightPrefabField = AccessTools.Field(typeof(CombatPhaseManager3D), "weightPrefab"); _showCardBlocked = AccessTools.Method(typeFromHandle, "ShowCardBlocked", new Type[1] { typeof(PlayableCard) }, (Type[])null); _preOverkillDamage = AccessTools.Method(typeFromHandle, "PreOverkillDamage", new Type[1] { typeof(PlayableCard) }, (Type[])null); _postOverkillDamage = AccessTools.Method(typeFromHandle, "PostOverkillDamage", new Type[1] { typeof(PlayableCard) }, (Type[])null); _visualizeClearSniper = AccessTools.Method(typeFromHandle, "VisualizeClearSniperAbility", Type.EmptyTypes, (Type[])null); } public static void UnlockAchievement(Achievement achievement) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (_unlockAchievement != null) { _unlockAchievement.Invoke(null, new object[1] { achievement }); } else { Debug.LogWarning((object)"[CombatBridge] UnlockAchievement 方法未找到"); } } public static GameObject GetWeightPrefab() { CombatPhaseManager instance = Singleton.Instance; CombatPhaseManager3D val = (CombatPhaseManager3D)(object)((instance is CombatPhaseManager3D) ? instance : null); if ((Object)(object)val == (Object)null || _weightPrefabField == null) { return null; } object? value = _weightPrefabField.GetValue(val); return (GameObject)((value is GameObject) ? value : null); } public static IEnumerator ShowCardBlocked(PlayableCard card) { if (!(_showCardBlocked == null)) { yield return _showCardBlocked.Invoke(Singleton.Instance, new object[1] { card }) as IEnumerator; } } public static IEnumerator PreOverkillDamage(PlayableCard queuedCard) { if (!(_preOverkillDamage == null)) { yield return _preOverkillDamage.Invoke(Singleton.Instance, new object[1] { queuedCard }) as IEnumerator; } } public static IEnumerator PostOverkillDamage(PlayableCard queuedCard) { if (!(_postOverkillDamage == null)) { yield return _postOverkillDamage.Invoke(Singleton.Instance, new object[1] { queuedCard }) as IEnumerator; } } public static void VisualizeClearSniperAbility() { if (_visualizeClearSniper != null) { _visualizeClearSniper.Invoke(Singleton.Instance, null); } } } public class FakeCombatHandler { public class FakeCombatThing { private List damageWeights = new List(); public static bool isCombatPhase; public static Ability ability; public int DamageDealtThisPhase { get; private set; } public IEnumerator FakeCombat(bool playerIsAttacker, SpecialBattleSequencer specialSequencer, CardSlot attacker, List overrideTargets = null, int overrideDMG = -1) { DamageDealtThisPhase = 0; yield return SlotAttackSequence(attacker, overrideTargets, overrideDMG); if (DamageDealtThisPhase > 0 && !isCombatPhase) { yield return (object)new WaitForSeconds(0.4f); yield return VisualizeDamageMovingToScales(playerIsAttacker); int excessDamage = 0; if (playerIsAttacker) { excessDamage = Singleton.Instance.Balance + DamageDealtThisPhase - 5; excessDamage = Mathf.Max(0, excessDamage); } int damage = DamageDealtThisPhase - excessDamage; if (DamageDealtThisPhase >= 666) { CombatBridge.UnlockAchievement((Achievement)25); } if ((Object)(object)specialSequencer == (Object)null || !specialSequencer.PreventDamageAddedToScales) { yield return Singleton.Instance.ShowDamageSequence(damage, damage, !playerIsAttacker, 0f, (GameObject)null, 0f, true); } if ((Object)(object)specialSequencer != (Object)null) { yield return specialSequencer.DamageAddedToScale(damage + excessDamage, playerIsAttacker); } if ((!((Object)(object)specialSequencer != (Object)null) || !specialSequencer.PreventDamageAddedToScales) && excessDamage > 0 && Singleton.Instance.Opponent.NumLives == 1 && Singleton.Instance.Opponent.GiveCurrencyOnDefeat) { yield return Singleton.Instance.Opponent.TryRevokeSurrender(); RunState run = RunState.Run; run.currency += excessDamage; } Singleton.Instance.Controller.LockState = (ViewLockState)0; DamageDealtThisPhase = 0; } } private IEnumerator VisualizeDamageMovingToScales(bool playerIsAttacker) { if ((Object)(object)Singleton.Instance.Scales3D != (Object)null) { Vector3 scalesPos = (playerIsAttacker ? Singleton.Instance.Scales3D.OpponentSide : Singleton.Instance.Scales3D.PlayerSide); foreach (Transform transform in damageWeights) { Tween.Position(transform, scalesPos, 0.2f, 0f, Tween.EaseOut, (LoopType)0, (Action)null, (Action)null, true); Object.Destroy((Object)(object)((Component)transform).gameObject, 0.2f); yield return (object)new WaitForSeconds(0.02f); } } else { foreach (Transform transform2 in damageWeights) { Part1Scales.DissolveWeight(((Component)transform2).gameObject); yield return (object)new WaitForSeconds(0.02f); } } yield return (object)new WaitForSeconds(0.25f); } public IEnumerator SpecialVisualiseAttacking(CardSlot attackingSlot, CardSlot targetSlot, int damage) { if (!Object.op_Implicit((Object)(object)Singleton.Instance)) { yield break; } if (Singleton.Instance is CombatPhaseManager3D) { List newWeights = new List(); GameObject weightPrefab = CombatBridge.GetWeightPrefab(); if ((Object)(object)weightPrefab == (Object)null) { yield break; } for (int i = 0; i < Mathf.Min(20, damage); i++) { GameObject gameObject = Object.Instantiate(weightPrefab); Vector3 vector = new Vector3(0f, 0f, attackingSlot.IsPlayerSlot ? 0.75f : (-0.75f)); gameObject.transform.position = ((Component)targetSlot).transform.position + vector + new Vector3((float)i * 0.1f, 0f, (float)i * 0.1f); gameObject.transform.eulerAngles = Random.insideUnitSphere; newWeights.Add(gameObject.transform); } damageWeights.AddRange(newWeights); ((Card)attackingSlot.Card).Anim.PlayAttackAnimation(true, targetSlot, (Action)delegate { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.ThumpTable(0.075f * (float)Mathf.Min(10, damage)); } foreach (Transform item in newWeights) { if ((Object)(object)item != (Object)null) { ((Component)item).gameObject.SetActive(true); ((Component)item).GetComponent().AddForce(Vector3.up * 4f, (ForceMode)2); } } }); } else { ((Card)attackingSlot.Card).Anim.PlayAttackAnimation(true, targetSlot, (Action)delegate { }); } } public IEnumerator SlotAttackSlot(CardSlot attackingSlot, CardSlot opposingSlot, float waitAfter = 0f, int overrideDMG = -1) { yield return Singleton.Instance.TriggerCardsOnBoard((Trigger)6, false, new object[2] { opposingSlot, attackingSlot.Card }); yield return (object)new WaitForSeconds(0.025f); if (!((Object)(object)attackingSlot.Card != (Object)null)) { yield break; } if (((Card)attackingSlot.Card).Anim.DoingAttackAnimation) { yield return (object)new WaitUntil((Func)(() => !((Card)attackingSlot.Card).Anim.DoingAttackAnimation)); yield return (object)new WaitForSeconds(0.25f); } if ((Object)(object)opposingSlot.Card != (Object)null && attackingSlot.Card.AttackIsBlocked(opposingSlot)) { ProgressionData.SetAbilityLearned((Ability)21); yield return CombatBridge.ShowCardBlocked(attackingSlot.Card); } else if (attackingSlot.Card.CanAttackDirectly(opposingSlot)) { DamageDealtThisPhase += ((overrideDMG > -1) ? overrideDMG : attackingSlot.Card.Attack); yield return SpecialVisualiseAttacking(attackingSlot, opposingSlot, (overrideDMG > -1) ? overrideDMG : attackingSlot.Card.Attack); if (attackingSlot.Card.TriggerHandler.RespondsToTrigger((Trigger)20, new object[1] { (overrideDMG > -1) ? overrideDMG : attackingSlot.Card.Attack })) { yield return attackingSlot.Card.TriggerHandler.OnTrigger((Trigger)20, new object[1] { (overrideDMG > -1) ? overrideDMG : attackingSlot.Card.Attack }); } } else { float heightOffset = (((Object)(object)opposingSlot.Card == (Object)null) ? 0f : opposingSlot.Card.SlotHeightOffset); if (heightOffset > 0f) { Tween.Position(((Component)attackingSlot.Card).transform, ((Component)attackingSlot.Card).transform.position + Vector3.up * heightOffset, 0.05f, 0f, Tween.EaseInOut, (LoopType)0, (Action)null, (Action)null, true); } ((Card)attackingSlot.Card).Anim.PlayAttackAnimation(attackingSlot.Card.IsFlyingAttackingReach(), opposingSlot, (Action)null); yield return (object)new WaitForSeconds(0.07f); ((Card)attackingSlot.Card).Anim.SetAnimationPaused(true); PlayableCard attackingCard = attackingSlot.Card; yield return Singleton.Instance.TriggerCardsOnBoard((Trigger)7, false, new object[1] { opposingSlot.Card }); if ((Object)(object)attackingCard != (Object)null && (Object)(object)attackingCard.Slot != (Object)null) { attackingSlot = attackingCard.Slot; if (attackingSlot.Card.IsFlyingAttackingReach()) { ((Card)opposingSlot.Card).Anim.PlayJumpAnimation(); yield return (object)new WaitForSeconds(0.3f); ((Card)attackingSlot.Card).Anim.PlayAttackInAirAnimation(); } ((Card)attackingSlot.Card).Anim.SetAnimationPaused(false); yield return (object)new WaitForSeconds(0.05f); int overkillDamage = ((overrideDMG > -1) ? (overrideDMG - opposingSlot.Card.Health) : (attackingSlot.Card.Attack - opposingSlot.Card.Health)); yield return opposingSlot.Card.TakeDamage((overrideDMG > -1) ? overrideDMG : attackingSlot.Card.Attack, attackingSlot.Card); yield return DealOverkillDamage(overkillDamage, attackingSlot, opposingSlot); if ((Object)(object)attackingSlot.Card != (Object)null && heightOffset > 0f) { yield return Singleton.Instance.AssignCardToSlot(attackingSlot.Card, attackingSlot.Card.Slot, 0.1f, (Action)null, false); } } } yield return (object)new WaitForSeconds(waitAfter); } private IEnumerator SlotAttackSequence(CardSlot slot, List overrideTargets = null, int overrideDMG = -1) { List opposingSlots = slot.Card.GetOpposingSlots(); if (overrideTargets != null) { opposingSlots = overrideTargets; } Singleton.Instance.SwitchToView(Singleton.Instance.CombatView, false, false); foreach (CardSlot opposingSlot in opposingSlots) { Singleton.Instance.SwitchToView(Singleton.Instance.CombatView, false, false); yield return SlotAttackSlot(slot, opposingSlot, (opposingSlots.Count > 1) ? 0.1f : 0f, overrideDMG); } CombatBridge.VisualizeClearSniperAbility(); } protected virtual IEnumerator DealOverkillDamage(int damage, CardSlot attackingSlot, CardSlot opposingSlot) { if (!((Object)(object)attackingSlot.Card != (Object)null) || !attackingSlot.IsPlayerSlot || damage <= 0) { yield break; } PlayableCard queuedCard = Singleton.Instance.GetCardQueuedForSlot(opposingSlot); if ((Object)(object)queuedCard != (Object)null) { yield return (object)new WaitForSeconds(0.1f); Singleton.Instance.SwitchToView(Singleton.Instance.QueueView, false, false); yield return (object)new WaitForSeconds(0.3f); if (queuedCard.HasAbility((Ability)21)) { yield return CombatBridge.ShowCardBlocked(attackingSlot.Card); yield break; } yield return CombatBridge.PreOverkillDamage(queuedCard); yield return queuedCard.TakeDamage(damage, attackingSlot.Card); yield return CombatBridge.PostOverkillDamage(queuedCard); } } } public static IEnumerator DoSimpleFakeCombat(int damage, CardSlot attacker, CardSlot target) { bool impactFrameReached = false; ((Card)attacker.Card).Anim.PlayAttackAnimation(false, target, (Action)delegate { impactFrameReached = true; }); yield return (object)new WaitUntil((Func)(() => impactFrameReached)); yield return target.Card.TakeDamage(damage, attacker.Card); } } } namespace NewCardsMod { [BepInPlugin("NewCards", "ForestUnderTheStarrySkyMod", "2.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(RunIntroSequencer))] public static class StarterDocilePatch { [HarmonyPostfix] [HarmonyPatch("TryModifyStarterCards")] public static void AddDocileToStarters() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown if (!AscensionSaveData.Data.ChallengeIsActive(DocileStarterChallengeID)) { return; } Ability enumValue = GuidManager.GetEnumValue("nevernamed.inscryption.sigils", "Docile"); if ((int)enumValue == 0) { Debug.LogError((object)"Count not find NevernamedSigils Docile!"); return; } foreach (CardInfo card in ((CardCollectionInfo)RunState.Run.playerDeck).Cards) { if (!card.HasTrait((Trait)13) && !card.HasAbility(enumValue)) { CardModificationInfo val = new CardModificationInfo(enumValue); RunState.Run.playerDeck.ModifyCard(card, val); } } } [HarmonyPostfix] [HarmonyPatch("RunIntroSequence")] public static IEnumerator ShowActivationAnnouncement(IEnumerator values) { if (AscensionSaveData.Data.ChallengeIsActive(DocileStarterChallengeID)) { ChallengeActivationUI.TryShowActivation(DocileStarterChallengeID); } yield return values; } } [HarmonyPatch(typeof(RunIntroSequencer))] public static class StarterCowardPatch { [HarmonyPostfix] [HarmonyPatch("TryModifyStarterCards")] public static void AddCowardToStarters() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown if (!AscensionSaveData.Data.ChallengeIsActive(CowardStarterChallengeID)) { return; } Ability enumValue = GuidManager.GetEnumValue("nevernamed.inscryption.sigils", "Coward"); if ((int)enumValue == 0) { Debug.LogError((object)"Count not find NevernamedSigils Coward!"); return; } foreach (CardInfo card in ((CardCollectionInfo)RunState.Run.playerDeck).Cards) { if (!card.HasTrait((Trait)13) && !card.HasAbility(enumValue)) { CardModificationInfo val = new CardModificationInfo(enumValue); RunState.Run.playerDeck.ModifyCard(card, val); } } } [HarmonyPostfix] [HarmonyPatch("RunIntroSequence")] public static IEnumerator ShowActivationAnnouncement(IEnumerator values) { if (AscensionSaveData.Data.ChallengeIsActive(DocileStarterChallengeID)) { ChallengeActivationUI.TryShowActivation(DocileStarterChallengeID); } yield return values; } } [HarmonyPatch(typeof(RunIntroSequencer))] public static class StarterEndangeredPatch { [HarmonyPostfix] [HarmonyPatch("TryModifyStarterCards")] public static void AddEndangeredToStarters() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown if (!AscensionSaveData.Data.ChallengeIsActive(CowardStarterChallengeID)) { return; } Ability enumValue = GuidManager.GetEnumValue("nevernamed.inscryption.sigils", "Endangered"); if ((int)enumValue == 0) { Debug.LogError((object)"Count not find NevernamedSigils Coward!"); return; } foreach (CardInfo card in ((CardCollectionInfo)RunState.Run.playerDeck).Cards) { if (!card.HasTrait((Trait)13) && !card.HasAbility(enumValue)) { CardModificationInfo val = new CardModificationInfo(enumValue); RunState.Run.playerDeck.ModifyCard(card, val); } } } [HarmonyPostfix] [HarmonyPatch("RunIntroSequence")] public static IEnumerator ShowActivationAnnouncement(IEnumerator values) { if (AscensionSaveData.Data.ChallengeIsActive(DocileStarterChallengeID)) { ChallengeActivationUI.TryShowActivation(DocileStarterChallengeID); } yield return values; } } public static AscensionChallenge DocileStarterChallengeID; public static AscensionChallenge CowardStarterChallengeID; public static AscensionChallenge EndangeredStarterChallengeID; private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Forest Under The Starry Sky Mod!"); addChallengeDoclieDeck(); Harmony val = new Harmony("NewCards"); val.PatchAll(typeof(StarterDocilePatch)); addChallengeCowardDeck(); Harmony val2 = new Harmony("NewCards"); val2.PatchAll(typeof(StarterCowardPatch)); addChallengeEndangeredDeck(); Harmony val3 = new Harmony("NewCards"); val3.PatchAll(typeof(StarterEndangeredPatch)); addExtremelyFastAttack(); addFanaticism(); addFortifiedArmor(); addKillingDesire(); addExtremitySprint(); addMonetaryRewards(); addImbalaneSuppression(); addRoar(); addMadCowDisease(); addUndercurrentsSurge(); addCornerSmash(); } private void addExtremelyFastAttack() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "ExtremelyFastAttack", "When [creature] is played, will direct attack once.", typeof(ExtremelyFastAttack), "ExtremelyFastAttack.png"), TextureHelper.GetImageAsTexture("Act2_ExtremelyFastAttack.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 4; val.rulebookName = "Extremely Fast Attack"; ExtremelyFastAttack.ability = val.ability; } private void addFanaticism() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "Fanaticism", "When [creature] is killed, it will attack once.", typeof(Fanaticism), "Fanaticism.png"), TextureHelper.GetImageAsTexture("Act2_Fanaticism.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 4; val.rulebookName = "Fanaticism"; ExtremelyFastAttack.ability = val.ability; } private void addFortifiedArmor() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "FortifiedArmor", " [creature] will reduce the damage they receive by one point when they are injured.", typeof(FortifiedArmor), "FortifiedArmor.png"), TextureHelper.GetImageAsTexture("Act2_FortifiedArmor.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 3; val.rulebookName = "Fortified Armor"; FortifiedArmor.ability = val.ability; } private void addKillingDesire() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "KillingDesire", "When [creature] is kill another card, the adjacent cards gain +1 health.", typeof(KillingDesire), "KillingDesire.png"), TextureHelper.GetImageAsTexture("Act2_KillingDesire.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 2; val.rulebookName = "KillingDesire"; KillingDesire.ability = val.ability; } private void addMonetaryRewards() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "MonetaryRewards", "When [creature] killing other cards, it will add a weight to the opposing side's balance.", typeof(MonetaryRewards), "MonetaryRewards.png"), TextureHelper.GetImageAsTexture("Act2_MonetaryRewards.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 2; val.rulebookName = "MonetaryRewards"; ExtremitySprint.ability = val.ability; } private void addImbalaneSuppression() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "ImbalaneSuppression", "When [creature] is present, after the opponent's turn ends, a weight will be added to the balance of the owner; and after the enemy's turn ends, a weight will be added to the balance of the opponent.", typeof(ImbalaneSuppression), "ImbalaneSuppression.png"), TextureHelper.GetImageAsTexture("Act2_ImbalaneSuppression.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = false; val.powerLevel = 2; val.rulebookName = "ImbalaneSuppression"; ExtremitySprint.ability = val.ability; } private void addExtremitySprint() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "ExtremitySprint", "At the end of the owner's turn, [creature] will move twice in the direction inscribed in the sigil.", typeof(ExtremitySprint), "ExtremitySprint.png"), TextureHelper.GetImageAsTexture("Act2_ExtremitySprint.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 1; val.rulebookName = "ExtremitySprint"; ExtremitySprint.ability = val.ability; } private void addRoar() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "Roar", "When [creature] is played, it reduces the all creatures on the opponent's -1 attack.", typeof(Roar), "Roar.png"), TextureHelper.GetImageAsTexture("Act2_Roar.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = false; val.powerLevel = 5; val.rulebookName = "Roar"; ExtremitySprint.ability = val.ability; } private void addMadCowDisease() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "MadCowDisease", "When [creature] is attacked,it will swap slot with attacker.", typeof(MadCowDisease), "MadCowDisease.png"), TextureHelper.GetImageAsTexture("Act2_MadCowDisease.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 0; val.rulebookName = "MadCowDisease"; BloodGuzzler.ability = val.ability; } private void addUndercurrentsSurge() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "UndercurrentsSurge", "When [creature] is played,it will give sigil 'Waterborne' to the opposing card.", typeof(UndercurrentsSurge), "UndercurrentsSurge.png"), TextureHelper.GetImageAsTexture("Act2_UndercurrentsSurge.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = false; val.powerLevel = 1; val.rulebookName = "UndercurrentsSurge"; BloodGuzzler.ability = val.ability; } private void addCornerSmash() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "CornerSmash", "When [creature] is moved, it will attack once.", typeof(CornerSmash), "CornerSmash.png"), TextureHelper.GetImageAsTexture("Act2_CornerSmash.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = false; val.powerLevel = 3; val.rulebookName = "CornerSmash"; BloodGuzzler.ability = val.ability; } private void addBloodGuzzler() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AbilityInfo val = AbilityExtensions.SetDefaultPart1Ability(AbilityExtensions.SetPixelAbilityIcon(AbilityManager.New("NewCards", "BloodGuzzler", "When [creature] deals damage, it gains 1 Health for each damage dealt.", typeof(BloodGuzzler), "BloodGuzzler.png"), TextureHelper.GetImageAsTexture("Act2_BloodGuzzler.png", (FilterMode)0), (FilterMode?)(FilterMode)0)); val.canStack = false; val.passive = false; val.activated = false; val.opponentUsable = true; val.powerLevel = 4; val.rulebookName = "Blood Guzzler"; BloodGuzzler.ability = val.ability; } private void addChallengeDoclieDeck() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) FullChallenge val = ChallengeManager.Add("NewCards", "Lose bestiality", "Give 'Doclie' sigil to all the cards in the starter deck.", 40, TextureHelper.GetImageAsTexture("LoseBestiality.png", (FilterMode)0), TextureHelper.GetImageAsTexture("LoseBestiality_Activated.png", (FilterMode)0), 0, false); DocileStarterChallengeID = val.Challenge.challengeType; } private void addChallengeCowardDeck() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) FullChallenge val = ChallengeManager.Add("NewCards", "Avoidance", "Give 'Coward' sigil to all the cards in the starter deck.", 25, TextureHelper.GetImageAsTexture("Avoidance.png", (FilterMode)0), TextureHelper.GetImageAsTexture("DefaultChallenge_activated.png", (FilterMode)0), 0, false); CowardStarterChallengeID = val.Challenge.challengeType; } private void addChallengeEndangeredDeck() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) FullChallenge val = ChallengeManager.Add("NewCards", "Unstable existence", "Give 'Endangered' sigil to all the cards in the starter deck.", 30, TextureHelper.GetImageAsTexture("Unstable existence.png", (FilterMode)0), TextureHelper.GetImageAsTexture("UnstableExistence_activated.png", (FilterMode)0), 0, false); EndangeredStarterChallengeID = val.Challenge.challengeType; } } public static class PluginInfo { public const string PLUGIN_GUID = "ForestUnderTheStarrySkyMod"; public const string PLUGIN_NAME = "ForestUnderTheStarrySkyMod"; public const string PLUGIN_VERSION = "2.0.0"; } public class ExtremelyFastAttack : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToResolveOnBoard() { return true; } public override IEnumerator OnResolveOnBoard() { yield return (object)new WaitForSeconds(0.1f); yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); yield return (object)new WaitForSeconds(0.1f); FakeCombatHandler.FakeCombatThing fakecombat = new FakeCombatHandler.FakeCombatThing(); yield return fakecombat.FakeCombat(!((AbilityBehaviour)this).Card.OpponentCard, null, ((AbilityBehaviour)this).Card.Slot); yield return (object)new WaitForSeconds(0.1f); } } public class Fanaticism : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { return (Object)(object)((AbilityBehaviour)this).Card == (Object)(object)killer && (Object)(object)killer != (Object)null && (Object)(object)((AbilityBehaviour)this).Card != (Object)null; } public override IEnumerator OnOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { yield return (object)new WaitForSeconds(0.1f); yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); yield return (object)new WaitForSeconds(0.1f); FakeCombatHandler.FakeCombatThing fakecombat = new FakeCombatHandler.FakeCombatThing(); yield return fakecombat.FakeCombat(!((AbilityBehaviour)this).Card.OpponentCard, null, ((AbilityBehaviour)this).Card.Slot); yield return (object)new WaitForSeconds(0.1f); } } public class FortifiedArmor : AbilityBehaviour, IModifyDamageTaken { public static Ability ability; public override Ability Ability => ability; public bool RespondsToModifyDamageTaken(PlayableCard target, int damage, PlayableCard attacker, int originalDamage) { return (Object)(object)target == (Object)(object)((AbilityBehaviour)this).Card && damage > 0; } public int OnModifyDamageTaken(PlayableCard target, int damage, PlayableCard attacker, int originalDamage) { ((Card)((AbilityBehaviour)this).Card).Anim.StrongNegationEffect(); return Mathf.Max(0, damage - 1); } public int TriggerPriority(PlayableCard target, int damage, PlayableCard attacker) { return 0; } } public class KillingDesire : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { return (Object)(object)killer == (Object)(object)((AbilityBehaviour)this).Card; } public override IEnumerator OnOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); CardSlot toLeft = Singleton.Instance.GetAdjacent(((AbilityBehaviour)this).Card.Slot, true); if ((Object)(object)toLeft != (Object)null && (Object)(object)toLeft.Card != (Object)null) { toLeft.Card.TemporaryMods.Add(new CardModificationInfo(0, 1)); } CardSlot toRight = Singleton.Instance.GetAdjacent(((AbilityBehaviour)this).Card.Slot, false); if ((Object)(object)toRight != (Object)null && (Object)(object)toRight.Card != (Object)null) { toRight.Card.TemporaryMods.Add(new CardModificationInfo(0, 1)); } ((AbilityBehaviour)this).Card.TemporaryMods.Add(new CardModificationInfo(0, 1)); yield return ((AbilityBehaviour)this).LearnAbility(0.25f); } } public class BloodGuzzler : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToDealDamage(int amount, PlayableCard target) { return CardExtensions.NotDead(((AbilityBehaviour)this).Card) && amount > 0; } public override IEnumerator OnDealDamage(int amount, PlayableCard target) { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); ((AbilityBehaviour)this).Card.AddTemporaryMod(new CardModificationInfo(0, amount)); ((AbilityBehaviour)this).Card.OnStatsChanged(); ((Card)((AbilityBehaviour)this).Card).Anim.StrongNegationEffect(); ((Card)((AbilityBehaviour)this).Card).RenderCard(); yield return (object)new WaitForSeconds(0.25f); yield return ((AbilityBehaviour)this).LearnAbility(0.25f); } } public class ExtremitySprint : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToTurnEnd(bool playerTurnEnd) { return ((AbilityBehaviour)this).Card.OpponentCard != playerTurnEnd; } public override bool RespondsToResolveOnBoard() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) CardExtensions.SetExtendedProperty(((Card)((AbilityBehaviour)this).Card).Info, "ExtremitySprintDirection", (object)"1"); if (((Card)((AbilityBehaviour)this).Card).RenderInfo != null && ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons != null && ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Contains(((AbilityBehaviour)this).Ability)) { ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Remove(((AbilityBehaviour)this).Ability); } return false; } public override IEnumerator OnTurnEnd(bool playerTurnEnd) { yield return MoveCardOnce(); yield return (object)new WaitForSeconds(0.3f); yield return MoveCardOnce(); } private IEnumerator MoveCardOnce() { CardSlot currentSlot = ((AbilityBehaviour)this).Card.Slot; if ((Object)(object)currentSlot == (Object)null) { yield break; } string dirStr = CardExtensions.GetExtendedProperty(((Card)((AbilityBehaviour)this).Card).Info, "ExtremitySprintDirection"); int direction = 1; if (!string.IsNullOrEmpty(dirStr) && int.TryParse(dirStr, out var parsed)) { direction = parsed; } if (direction != 1 && direction != -1) { direction = 1; } CardSlot targetSlot = ((direction == 1) ? CardSlotExtensions.GetAdjacent(currentSlot, false) : CardSlotExtensions.GetAdjacent(currentSlot, true)); if ((Object)(object)targetSlot == (Object)null || (Object)(object)targetSlot.Card != (Object)null) { direction *= -1; CardExtensions.SetExtendedProperty(((Card)((AbilityBehaviour)this).Card).Info, "ExtremitySprintDirection", (object)direction.ToString()); if (((Card)((AbilityBehaviour)this).Card).RenderInfo != null) { if (((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons == null) { ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons = new List(); } if (direction == -1) { if (!((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Contains(((AbilityBehaviour)this).Ability)) { ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Add(((AbilityBehaviour)this).Ability); } } else if (((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Contains(((AbilityBehaviour)this).Ability)) { ((Card)((AbilityBehaviour)this).Card).RenderInfo.flippedAbilityIcons.Remove(((AbilityBehaviour)this).Ability); } } targetSlot = ((direction == 1) ? CardSlotExtensions.GetAdjacent(currentSlot, false) : CardSlotExtensions.GetAdjacent(currentSlot, true)); } if ((Object)(object)targetSlot != (Object)null && (Object)(object)targetSlot.Card == (Object)null) { yield return CardSlotExtensions.AssignCardToSlot(targetSlot, ((AbilityBehaviour)this).Card, 0.1f, (Action)null, true); } } } public class MonetaryRewards : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { return (Object)(object)killer == (Object)(object)((AbilityBehaviour)this).Card; } public override IEnumerator OnOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer) { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); yield return Singleton.Instance.ShowDamageSequence(1, 1, !((AbilityBehaviour)this).Card.Slot.IsPlayerSlot, 0.25f, (GameObject)null, 0f, true); } } public class ImbalaneSuppression : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToTurnEnd(bool PlayerTurn) { return true; } public override IEnumerator OnTurnEnd(bool playerTurn) { yield return (object)new WaitForSeconds(0.15f); bool damageToPlayer = !playerTurn; yield return Singleton.Instance.ShowDamageSequence(1, 1, damageToPlayer, 0.25f, (GameObject)null, 0f, true); yield return (object)new WaitForSeconds(0.1f); } } public class Roar : AbilityBehaviour { private Dictionary debuffs = new Dictionary(); public static Ability ability; public override Ability Ability => ability; private void ApplyDebuff(PlayableCard target) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (!((Object)(object)target == (Object)null) && !target.Dead && !debuffs.ContainsKey(target)) { CardModificationInfo val = new CardModificationInfo(-1, 0); target.AddTemporaryMod(val); debuffs[target] = val; } } private void RemoveAllDebuffs() { List list = new List(); foreach (KeyValuePair debuff in debuffs) { if ((Object)(object)debuff.Key != (Object)null && !debuff.Key.Dead) { debuff.Key.RemoveTemporaryMod(debuff.Value, true); } list.Add(debuff.Key); } foreach (PlayableCard item in list) { debuffs.Remove(item); } } private void ApplyToAllEnemies() { foreach (CardSlot item in Singleton.Instance.OpponentSlotsCopy) { if ((Object)(object)item.Card != (Object)null) { ApplyDebuff(item.Card); } } } public override bool RespondsToResolveOnBoard() { ApplyToAllEnemies(); return false; } public override bool RespondsToOtherCardResolve(PlayableCard other) { if (other.OpponentCard) { ApplyDebuff(other); } return false; } public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer) { RemoveAllDebuffs(); return false; } public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer) { RemoveAllDebuffs(); yield break; } } public class MadCowDisease : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToTakeDamage(PlayableCard attacker) { return (Object)(object)((AbilityBehaviour)this).Card != (Object)null && (Object)(object)attacker != (Object)null && CardExtensions.NotDead(((AbilityBehaviour)this).Card) && !attacker.HasAbility((Ability)105); } public override IEnumerator OnTakeDamage(PlayableCard source) { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); CardSlot mySlot = ((AbilityBehaviour)this).Card.Slot; CardSlot attackerSlot = source.Slot; if (!((Object)(object)mySlot == (Object)null) && !((Object)(object)attackerSlot == (Object)null) && !source.Dead && source.OnBoard) { PlayableCard myCard = ((AbilityBehaviour)this).Card; yield return CardSlotExtensions.AssignCardToSlot(attackerSlot, myCard, 0.1f, (Action)null, true); yield return CardSlotExtensions.AssignCardToSlot(mySlot, source, 0.1f, (Action)null, true); } } } public class UndercurrentsSurge : AbilityBehaviour { public static Ability ability; public override Ability Ability => ability; public override bool RespondsToResolveOnBoard() { return (Object)(object)((AbilityBehaviour)this).Card != (Object)null && ((AbilityBehaviour)this).Card.OnBoard && !((AbilityBehaviour)this).Card.Dead; } public override IEnumerator OnResolveOnBoard() { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); CardSlot opposingSlot = ((AbilityBehaviour)this).Card.Slot.opposingSlot; if (!((Object)(object)opposingSlot == (Object)null)) { PlayableCard target = opposingSlot.Card; if (!((Object)(object)target == (Object)null) && !target.Dead) { target.AddTemporaryMod(new CardModificationInfo((Ability)13)); target.OnStatsChanged(); ((Card)target).RenderCard(); ((Card)target).Anim.StrongNegationEffect(); } } } } public class CornerSmash : AbilityBehaviour { private bool hasResolved; public static Ability ability; public override Ability Ability => ability; public override bool RespondsToResolveOnBoard() { return true; } public override IEnumerator OnResolveOnBoard() { hasResolved = true; yield break; } public override bool RespondsToOtherCardAssignedToSlot(PlayableCard otherCard) { if (!hasResolved || (Object)(object)otherCard != (Object)(object)((AbilityBehaviour)this).Card) { return false; } if ((Object)(object)((AbilityBehaviour)this).Card == (Object)null || ((AbilityBehaviour)this).Card.Dead || (Object)(object)((AbilityBehaviour)this).Card.Slot == (Object)null) { return false; } return true; } public override IEnumerator OnOtherCardAssignedToSlot(PlayableCard otherCard) { yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence(); FakeCombatHandler.FakeCombatThing fakeCombat = new FakeCombatHandler.FakeCombatThing(); yield return fakeCombat.FakeCombat(!((AbilityBehaviour)this).Card.OpponentCard, null, ((AbilityBehaviour)this).Card.Slot); } } }