diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 4e54a2b731a..5126f906227 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -177,16 +177,16 @@ public class ComputerUtilCombat { public static int damageIfUnblocked(final Card attacker, final GameEntity attacked, final Combat combat, boolean withoutAbilities) { int damage = attacker.getNetCombatDamage(); int sum = 0; - if (attacked instanceof Player player && !player.canLoseLife()) { - return 0; - } - - // ask ReplacementDamage directly - if (isCombatDamagePrevented(attacker, attacked, damage)) { + if (attacked instanceof Player p && !p.canLoseLife()) { return 0; } if (!attacker.hasKeyword(Keyword.INFECT)) { + // ask ReplacementDamage directly + if (isCombatDamagePrevented(attacker, attacked, damage)) { + return 0; + } + damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities); sum = predictDamageTo(attacked, damage, attacker, true); if (attacker.hasDoubleStrike()) { diff --git a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java index dc9f5b16e02..f8c6060117a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java @@ -135,9 +135,7 @@ public class CounterAi extends SpellAbilityAi { if (sa.hasParam("AILogic")) { String logic = sa.getParam("AILogic"); - if ("Never".equals(logic)) { - return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); - } else if (logic.startsWith("MinCMC.")) { // TODO fix Daze and fold into AITgts + if (logic.startsWith("MinCMC.")) { // TODO fix Daze and fold into AITgts int minCMC = Integer.parseInt(logic.substring(7)); if (tgtCMC < minCMC) { return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); diff --git a/forge-ai/src/main/java/forge/ai/ability/DigMultipleAi.java b/forge-ai/src/main/java/forge/ai/ability/DigMultipleAi.java index a6ff092ffbc..9a646b9e0d2 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DigMultipleAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DigMultipleAi.java @@ -37,10 +37,6 @@ public class DigMultipleAi extends SpellAbilityAi { return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); } - if ("Never".equals(sa.getParam("AILogic"))) { - return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); - } - // don't deck yourself if (sa.hasParam("DestinationZone2") && !"Library".equals(sa.getParam("DestinationZone2"))) { int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index e53361d4ce8..407e794ebd3 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -170,9 +170,11 @@ public final class StaticAbilityContinuous { addKeywords = Lists.newArrayList(Arrays.asList(params.get("AddKeyword").split(" & "))); final List newKeywords = Lists.newArrayList(); - // update keywords with Chosen parts - final String hostCardUID = Integer.toString(hostCard.getId()); // Protection with "doesn't remove" effect + // Protection with "doesn't remove" effect + final String hostCardUID = Integer.toString(hostCard.getId()); + final String hostCardControllerUID = Integer.toString(hostCard.getController().getId()); + // update keywords with Chosen parts addKeywords.removeIf(input -> { if (!hostCard.hasChosenColor() && input.contains("ChosenColor")) { return true; @@ -285,6 +287,7 @@ public final class StaticAbilityContinuous { input = input.replaceAll("chosenEvenOdd", hostCard.getChosenEvenOdd().toString().toLowerCase()); } input = input.replace("HostCardUID", hostCardUID); + input = input.replace("HostCardControllerUID", hostCardControllerUID); if (params.containsKey("CalcKeywordN")) { input = input.replace("N", String.valueOf(AbilityUtils.calculateAmount(hostCard, params.get("CalcKeywordN"), stAb))); } diff --git a/forge-gui/res/cardsfolder/b/benevolent_blessing.txt b/forge-gui/res/cardsfolder/b/benevolent_blessing.txt index c109b73970d..bea6937fef1 100644 --- a/forge-gui/res/cardsfolder/b/benevolent_blessing.txt +++ b/forge-gui/res/cardsfolder/b/benevolent_blessing.txt @@ -6,5 +6,5 @@ K:Enchant:Creature K:ETBReplacement:Other:ChooseColor SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInHumanDeck | SpellDescription$ As CARDNAME enters, choose a color. SVar:AttachAILogic:Pump -S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:chosenColor:Aura.YouCtrl,Equipment.YouCtrl:SBA | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove Auras and Equipment you control that are already attached to it. +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Protection:Card.ChosenColor:chosenColor:Aura.ControlledBy Player.PlayerUID_HostCardControllerUID,Equipment.ControlledBy Player.PlayerUID_HostCardControllerUID:SBA | Description$ Enchanted creature has protection from the chosen color. This effect doesn't remove Auras and Equipment you control that are already attached to it. Oracle:Flash\nEnchant creature\nAs Benevolent Blessing enters, choose a color.\nEnchanted creature has protection from the chosen color. This effect doesn't remove Auras and Equipment you control that are already attached to it. diff --git a/forge-gui/res/cardsfolder/m/maralen_of_the_mornsong.txt b/forge-gui/res/cardsfolder/m/maralen_of_the_mornsong.txt index 31c3678c2c0..0b86615bc6d 100644 --- a/forge-gui/res/cardsfolder/m/maralen_of_the_mornsong.txt +++ b/forge-gui/res/cardsfolder/m/maralen_of_the_mornsong.txt @@ -5,6 +5,6 @@ PT:2/3 S:Mode$ CantDraw | ValidPlayer$ Player | Description$ Players can't draw cards. T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ At the beginning of each player's draw step, that player loses 3 life, searches their library for a card, puts it into their hand, then shuffles. SVar:TrigDrain:DB$ LoseLife | Defined$ TriggeredPlayer | LifeAmount$ 3 | SubAbility$ DBTutor -SVar:DBTutor:DB$ ChangeZone | DefinedPlayer$ TriggeredPlayer | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 +SVar:DBTutor:DB$ ChangeZone | DefinedPlayer$ TriggeredPlayer | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True AI:RemoveDeck:Random Oracle:Players can't draw cards.\nAt the beginning of each player's draw step, that player loses 3 life, searches their library for a card, puts it into their hand, then shuffles. diff --git a/forge-gui/res/cardsfolder/s/spinal_embrace.txt b/forge-gui/res/cardsfolder/s/spinal_embrace.txt index b3444c068c6..4d3b6fae407 100644 --- a/forge-gui/res/cardsfolder/s/spinal_embrace.txt +++ b/forge-gui/res/cardsfolder/s/spinal_embrace.txt @@ -2,7 +2,7 @@ Name:Spinal Embrace ManaCost:3 U U B Types:Instant A:SP$ Untap | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | ActivationPhases$ BeginCombat->EndCombat | SubAbility$ DBChange | SpellDescription$ Cast this spell only during combat. Untap target creature you don't control and gain control of it. It gains haste until end of turn. At the beginning of the next end step, sacrifice it. If you do, you gain life equal to its toughness. -SVar:DBChange:DB$ GainControl | Defined$ Targeted | SubAbility$ DBAnimate +SVar:DBChange:DB$ GainControl | Defined$ Targeted | AddKWs$ Haste | SubAbility$ DBAnimate SVar:DBAnimate:DB$ Animate | Defined$ Targeted | sVars$ SneakAttackEOT | SubAbility$ DelTrig SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End Of Turn | Execute$ TrigSac | RememberObjects$ Targeted | TriggerDescription$ At the beginning of the next end step, sacrifice it. If you do, you gain life equal to its toughness. | AILogic$ Always | ConditionDefined$ Targeted | ConditionPresent$ Card | ConditionCompare$ GE1 SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You | RememberSacrificed$ True | SubAbility$ DBGainLife diff --git a/forge-gui/res/cardsfolder/s/steel_dromedary.txt b/forge-gui/res/cardsfolder/s/steel_dromedary.txt index 79ac5a7a8d8..f64b86b2a1b 100644 --- a/forge-gui/res/cardsfolder/s/steel_dromedary.txt +++ b/forge-gui/res/cardsfolder/s/steel_dromedary.txt @@ -7,6 +7,6 @@ SVar:CamelTapped:DB$ Tap | Defined$ Self | ETB$ True | SubAbility$ DBAddCounter SVar:DBAddCounter:DB$ PutCounter | ETB$ True | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 R:Event$ Untap | ActiveZones$ Battlefield | ValidCard$ Card.Self+counters_GE1_P1P1 | ValidStepTurnToController$ You | Layer$ CantHappen | Description$ CARDNAME doesn't untap during your untap step if it has a +1/+1 counter on it. T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigMoveCounter | TriggerDescription$ At the beginning of combat on your turn, you may move a +1/+1 counter from CARDNAME onto target creature. -SVar:TrigMoveCounter:DB$ MoveCounter | ValidTgts$ Creature.Other | TgtPrompt$ Select another target creature | Source$ Self | CounterType$ P1P1 | CounterNum$ 1 +SVar:TrigMoveCounter:DB$ MoveCounter | ValidTgts$ Creature | Source$ Self | CounterType$ P1P1 | CounterNum$ 1 DeckHas:Ability$Counters Oracle:Steel Dromedary enters tapped with two +1/+1 counters on it.\nSteel Dromedary doesn't untap during your untap step if it has a +1/+1 counter on it.\nAt the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature.