Benevolent Blessing: fix exception ignoring opponent auras (#8870)

This commit is contained in:
tool4ever
2025-10-08 20:58:12 +02:00
committed by GitHub
parent 7f02c73090
commit b844181c0b
8 changed files with 16 additions and 19 deletions

View File

@@ -177,16 +177,16 @@ public class ComputerUtilCombat {
public static int damageIfUnblocked(final Card attacker, final GameEntity attacked, final Combat combat, boolean withoutAbilities) { public static int damageIfUnblocked(final Card attacker, final GameEntity attacked, final Combat combat, boolean withoutAbilities) {
int damage = attacker.getNetCombatDamage(); int damage = attacker.getNetCombatDamage();
int sum = 0; int sum = 0;
if (attacked instanceof Player player && !player.canLoseLife()) { if (attacked instanceof Player p && !p.canLoseLife()) {
return 0;
}
// ask ReplacementDamage directly
if (isCombatDamagePrevented(attacker, attacked, damage)) {
return 0; return 0;
} }
if (!attacker.hasKeyword(Keyword.INFECT)) { if (!attacker.hasKeyword(Keyword.INFECT)) {
// ask ReplacementDamage directly
if (isCombatDamagePrevented(attacker, attacked, damage)) {
return 0;
}
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities); damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
sum = predictDamageTo(attacked, damage, attacker, true); sum = predictDamageTo(attacked, damage, attacker, true);
if (attacker.hasDoubleStrike()) { if (attacker.hasDoubleStrike()) {

View File

@@ -135,9 +135,7 @@ public class CounterAi extends SpellAbilityAi {
if (sa.hasParam("AILogic")) { if (sa.hasParam("AILogic")) {
String logic = sa.getParam("AILogic"); String logic = sa.getParam("AILogic");
if ("Never".equals(logic)) { if (logic.startsWith("MinCMC.")) { // TODO fix Daze and fold into AITgts
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
} else if (logic.startsWith("MinCMC.")) { // TODO fix Daze and fold into AITgts
int minCMC = Integer.parseInt(logic.substring(7)); int minCMC = Integer.parseInt(logic.substring(7));
if (tgtCMC < minCMC) { if (tgtCMC < minCMC) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);

View File

@@ -37,10 +37,6 @@ public class DigMultipleAi extends SpellAbilityAi {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
} }
if ("Never".equals(sa.getParam("AILogic"))) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
// don't deck yourself // don't deck yourself
if (sa.hasParam("DestinationZone2") && !"Library".equals(sa.getParam("DestinationZone2"))) { if (sa.hasParam("DestinationZone2") && !"Library".equals(sa.getParam("DestinationZone2"))) {
int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa); int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa);

View File

@@ -170,9 +170,11 @@ public final class StaticAbilityContinuous {
addKeywords = Lists.newArrayList(Arrays.asList(params.get("AddKeyword").split(" & "))); addKeywords = Lists.newArrayList(Arrays.asList(params.get("AddKeyword").split(" & ")));
final List<String> newKeywords = Lists.newArrayList(); final List<String> newKeywords = Lists.newArrayList();
// update keywords with Chosen parts // Protection with "doesn't remove" effect
final String hostCardUID = Integer.toString(hostCard.getId()); // 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 -> { addKeywords.removeIf(input -> {
if (!hostCard.hasChosenColor() && input.contains("ChosenColor")) { if (!hostCard.hasChosenColor() && input.contains("ChosenColor")) {
return true; return true;
@@ -285,6 +287,7 @@ public final class StaticAbilityContinuous {
input = input.replaceAll("chosenEvenOdd", hostCard.getChosenEvenOdd().toString().toLowerCase()); input = input.replaceAll("chosenEvenOdd", hostCard.getChosenEvenOdd().toString().toLowerCase());
} }
input = input.replace("HostCardUID", hostCardUID); input = input.replace("HostCardUID", hostCardUID);
input = input.replace("HostCardControllerUID", hostCardControllerUID);
if (params.containsKey("CalcKeywordN")) { if (params.containsKey("CalcKeywordN")) {
input = input.replace("N", String.valueOf(AbilityUtils.calculateAmount(hostCard, params.get("CalcKeywordN"), stAb))); input = input.replace("N", String.valueOf(AbilityUtils.calculateAmount(hostCard, params.get("CalcKeywordN"), stAb)));
} }

View File

@@ -6,5 +6,5 @@ K:Enchant:Creature
K:ETBReplacement:Other:ChooseColor K:ETBReplacement:Other:ChooseColor
SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInHumanDeck | SpellDescription$ As CARDNAME enters, choose a color. SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInHumanDeck | SpellDescription$ As CARDNAME enters, choose a color.
SVar:AttachAILogic:Pump 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. 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.

View File

@@ -5,6 +5,6 @@ PT:2/3
S:Mode$ CantDraw | ValidPlayer$ Player | Description$ Players can't draw cards. 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. 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: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 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. 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.

View File

@@ -2,7 +2,7 @@ Name:Spinal Embrace
ManaCost:3 U U B ManaCost:3 U U B
Types:Instant 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. 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: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: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 SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You | RememberSacrificed$ True | SubAbility$ DBGainLife

View File

@@ -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 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. 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. 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 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. 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.