diff --git a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java index a1a93174e8d..36907ed6ea9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java @@ -11,6 +11,7 @@ import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; +import forge.game.card.CardPredicates.Presets; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.keyword.Keyword; @@ -30,6 +31,7 @@ import forge.util.MyRandom; import forge.util.TextUtil; import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -68,6 +70,41 @@ public class EffectAi extends SpellAbilityAi { } randomReturn = true; } + } else if (logic.equals("RestrictBlocking")) { + if (!phase.isPlayerTurn(ai) || phase.getPhase().isBefore(PhaseType.COMBAT_BEGIN) + || phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { + return false; + } + + if (sa.getPayCosts().getTotalMana().countX() > 0 && sa.getHostCard().getSVar("X").equals("Count$xPaid")) { + // Set PayX here to half the remaining mana to allow for Main 2 and other combat shenanigans. + final int xPay = ComputerUtilMana.determineLeftoverMana(sa, ai, sa.isTrigger()) / 2; + if (xPay == 0) { return false; } + sa.setXManaCostPaid(xPay); + } + + Player opp = ai.getStrongestOpponent(); + List possibleAttackers = ai.getCreaturesInPlay(); + List possibleBlockers = opp.getCreaturesInPlay(); + possibleBlockers = CardLists.filter(possibleBlockers, Presets.UNTAPPED); + final Combat combat = game.getCombat(); + int oppLife = opp.getLife(); + int potentialDmg = 0; + List currentAttackers = new ArrayList<>(); + + if (possibleBlockers.isEmpty()) { return false; } + + for (final Card creat : possibleAttackers) { + if (CombatUtil.canAttack(creat, opp) && possibleBlockers.size() > 1) { + potentialDmg += creat.getCurrentPower(); + if (potentialDmg >= oppLife) { return true; } + } + if (combat != null && combat.isAttacking(creat)) { + currentAttackers.add(creat); + } + } + + return currentAttackers.size() > possibleBlockers.size(); } else if (logic.equals("Fog")) { FogAi fogAi = new FogAi(); if (!fogAi.canPlayAI(ai, sa)) { diff --git a/forge-ai/src/main/java/forge/ai/ability/StoreSVarAi.java b/forge-ai/src/main/java/forge/ai/ability/StoreSVarAi.java index f2cd01e86d1..70e71c05114 100644 --- a/forge-ai/src/main/java/forge/ai/ability/StoreSVarAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/StoreSVarAi.java @@ -1,18 +1,6 @@ package forge.ai.ability; -import java.util.ArrayList; -import java.util.List; - -import forge.ai.ComputerUtilMana; import forge.ai.SpellAbilityAi; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates.Presets; -import forge.game.combat.Combat; -import forge.game.combat.CombatUtil; -import forge.game.phase.PhaseHandler; -import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.trigger.WrappedAbility; @@ -21,51 +9,6 @@ public class StoreSVarAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Card source = sa.getHostCard(); - final Game game = ai.getGame(); - final Combat combat = game.getCombat(); - final PhaseHandler ph = game.getPhaseHandler(); - final Player opp = ai.getOpponents().get(0); - - if (sa.hasParam("AILogic")) { - if (sa.getPayCosts().getTotalMana().countX() > 0 && source.getSVar("X").equals("Count$xPaid")) { - // Set PayX here to half the remaining mana to allow for Main 2 and other combat shenanigans. - final int xPay = ComputerUtilMana.determineLeftoverMana(sa, ai, sa.isTrigger()) / 2; - if (xPay == 0) { return false; } - sa.setXManaCostPaid(xPay); - } - - final String logic = sa.getParam("AILogic"); - if (logic.equals("RestrictBlocking")) { - if (!ph.isPlayerTurn(ai) || ph.getPhase().isBefore(PhaseType.COMBAT_BEGIN) - || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { - return false; - } - - List possibleAttackers = ai.getCreaturesInPlay(); - List possibleBlockers = opp.getCreaturesInPlay(); - possibleBlockers = CardLists.filter(possibleBlockers, Presets.UNTAPPED); - int oppLife = opp.getLife(); - int potentialDmg = 0; - List currentAttackers = new ArrayList<>(); - - if (possibleBlockers.size() == 0) { return false; } - - for (final Card creat : possibleAttackers) { - if (CombatUtil.canAttack(creat, opp) && possibleBlockers.size() > 1) { - potentialDmg += creat.getCurrentPower(); - if (potentialDmg >= oppLife) { return true; } - } - if (combat != null && combat.isAttacking(creat)) { - currentAttackers.add(creat); - } - } - - return currentAttackers.size() > possibleBlockers.size(); - } - return false; - } - return true; } diff --git a/forge-game/src/main/java/forge/game/combat/CombatUtil.java b/forge-game/src/main/java/forge/game/combat/CombatUtil.java index 8b283ecaccc..6f014c1ae52 100644 --- a/forge-game/src/main/java/forge/game/combat/CombatUtil.java +++ b/forge-game/src/main/java/forge/game/combat/CombatUtil.java @@ -286,6 +286,10 @@ public class CombatUtil { // If there's a better way of handling this somewhere deeper in the code, feel free to remove final SpellAbility fakeSA = new SpellAbility.EmptySa(attacker, attacker.getController()); fakeSA.setCardState(attacker.getCurrentState()); + // need to set this for "CostContainsX" restriction + fakeSA.setPayCosts(attackCost); + // prevent recalculating X + fakeSA.setSVar("X", "0"); return attacker.getController().getController().payManaOptional(attacker, attackCost, fakeSA, "Pay additional cost to declare " + attacker + " an attacker", ManaPaymentPurpose.DeclareAttacker); } @@ -347,6 +351,8 @@ public class CombatUtil { SpellAbility fakeSA = new SpellAbility.EmptySa(blocker, blocker.getController()); fakeSA.setCardState(blocker.getCurrentState()); + fakeSA.setPayCosts(blockCost); + fakeSA.setSVar("X", "0"); return blocker.getController().getController().payManaOptional(blocker, blockCost, fakeSA, "Pay cost to declare " + blocker + " a blocker. ", ManaPaymentPurpose.DeclareBlocker); } diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index 8aa399dc86d..ed79039d1ef 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -138,7 +138,7 @@ public class CostPartMana extends CostPart { if (isCostPayAnyNumberOfTimes) { int timesToPay = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getSVar("NumTimes"), sa); if (timesToPay == 0) { - return ManaCost.NO_COST; + return ManaCost.ZERO; } ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getMana()); for (int i = 1; i < timesToPay; i++) { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java index 6ed4d716c8c..f367e97a7b2 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java @@ -254,7 +254,12 @@ public class StaticAbilityCantAttackBlock { if (remember) { hostCard.addRemembered(attacker); } + // keep X shards + boolean addX = costString.startsWith("X"); costString = Integer.toString(AbilityUtils.calculateAmount(hostCard, stAb.getSVar(costString), stAb)); + if (addX) { + costString += " X"; + } if (remember) { hostCard.removeRemembered(attacker); } @@ -288,7 +293,11 @@ public class StaticAbilityCantAttackBlock { } String costString = stAb.getParam("Cost"); if (stAb.hasSVar(costString)) { - costString = Integer.toString(AbilityUtils.calculateAmount(hostCard, costString, stAb)); + boolean addX = costString.startsWith("X"); + costString = Integer.toString(AbilityUtils.calculateAmount(hostCard, stAb.getSVar(costString), stAb)); + if (addX) { + costString += " X"; + } } return new Cost(costString, true); diff --git a/forge-gui/res/cardsfolder/c/cowed_by_wisdom.txt b/forge-gui/res/cardsfolder/c/cowed_by_wisdom.txt index cf0d3200e6a..ee9eccaf22f 100644 --- a/forge-gui/res/cardsfolder/c/cowed_by_wisdom.txt +++ b/forge-gui/res/cardsfolder/c/cowed_by_wisdom.txt @@ -3,7 +3,7 @@ ManaCost:W Types:Enchantment Aura K:Enchant creature A:SP$ Attach | Cost$ W | ValidTgts$ Creature | AILogic$ Curse -S:Mode$ CantAttackUnless | ValidCard$ Creature.AttachedBy | Cost$ X | Description$ Enchanted creature can't attack or block unless its controller pays {1} for each card in your hand. -S:Mode$ CantBlockUnless | ValidCard$ Creature.AttachedBy | Cost$ X -SVar:X:Count$InYourHand +S:Mode$ CantAttackUnless | ValidCard$ Creature.AttachedBy | Cost$ Y | Description$ Enchanted creature can't attack or block unless its controller pays {1} for each card in your hand. +S:Mode$ CantBlockUnless | ValidCard$ Creature.AttachedBy | Cost$ Y +SVar:Y:Count$InYourHand Oracle:Enchant creature\nEnchanted creature can't attack or block unless its controller pays {1} for each card in your hand. diff --git a/forge-gui/res/cardsfolder/l/lazav_wearer_of_faces.txt b/forge-gui/res/cardsfolder/l/lazav_wearer_of_faces.txt index 8f60079185b..47bede35b35 100644 --- a/forge-gui/res/cardsfolder/l/lazav_wearer_of_faces.txt +++ b/forge-gui/res/cardsfolder/l/lazav_wearer_of_faces.txt @@ -6,7 +6,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Card | SubAbility$ DBInvestigate SVar:DBInvestigate:DB$ Investigate T:Mode$ Sacrificed | ValidPlayer$ You | ValidCard$ Clue.YouCtrl | Execute$ TrigClone | TriggerZones$ Battlefield | TriggerDescription$ Whenever you sacrifice a Clue, you may have NICKNAME become a copy of a creature card exiled with it until end of turn. -SVar:TrigClone:DB$ Clone | Choices$ Creature.ExiledWithSource | ChoiceZone$ Exile | Optional$ True +SVar:TrigClone:DB$ Clone | Choices$ Creature.ExiledWithSource | ChoiceZone$ Exile | Optional$ True | Duration$ UntilEndOfTurn SVar:HasAttackEffect:TRUE DeckHas:Ability$Investigate|Token|Graveyard & Type$Artifact|Clue DeckHints:Ability$Graveyard diff --git a/forge-gui/res/cardsfolder/m/mine_raider.txt b/forge-gui/res/cardsfolder/m/mine_raider.txt index f03d7a82019..bb502bd07e7 100644 --- a/forge-gui/res/cardsfolder/m/mine_raider.txt +++ b/forge-gui/res/cardsfolder/m/mine_raider.txt @@ -3,7 +3,7 @@ ManaCost:2 R Types:Creature Human Rogue PT:3/2 K:Trample -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | IsPresent$ Card.Outlaw+StrictlyOther | TriggerZones$ Battlefield | Execute$ TrigTreasure | TriggerDescription$ When CARDNAME enters the battlefield, if you control another outlaw, create a Treasure token. (Assassins, Mercenaries, Pirates, Rogues, and Warlocks are outlaws. A Treasure token is an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.") +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | IsPresent$ Card.Outlaw+StrictlyOther+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigTreasure | TriggerDescription$ When CARDNAME enters the battlefield, if you control another outlaw, create a Treasure token. (Assassins, Mercenaries, Pirates, Rogues, and Warlocks are outlaws. A Treasure token is an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.") SVar:TrigTreasure:DB$ Token | TokenScript$ c_a_treasure_sac DeckHas:Ability$Token|Sacrifice & Type$Artifact|Treasure Oracle:Trample\nWhen Mine Raider enters the battlefield, if you control another outlaw, create a Treasure token. (Assassins, Mercenaries, Pirates, Rogues, and Warlocks are outlaws. A Treasure token is an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.") diff --git a/forge-gui/res/cardsfolder/m/myr_prototype.txt b/forge-gui/res/cardsfolder/m/myr_prototype.txt index 38b7dc41aa2..0ce0e5b15d4 100644 --- a/forge-gui/res/cardsfolder/m/myr_prototype.txt +++ b/forge-gui/res/cardsfolder/m/myr_prototype.txt @@ -4,7 +4,7 @@ Types:Artifact Creature Myr PT:2/2 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 -S:Mode$ CantAttackUnless | ValidCard$ Card.Self | Cost$ X | Description$ CARDNAME can't attack or block unless you pay {1} for each +1/+1 counter on it. -S:Mode$ CantBlockUnless | ValidCard$ Card.Self | Cost$ X -SVar:X:Count$CardCounters.P1P1 +S:Mode$ CantAttackUnless | ValidCard$ Card.Self | Cost$ Y | Description$ CARDNAME can't attack or block unless you pay {1} for each +1/+1 counter on it. +S:Mode$ CantBlockUnless | ValidCard$ Card.Self | Cost$ Y +SVar:Y:Count$CardCounters.P1P1 Oracle:At the beginning of your upkeep, put a +1/+1 counter on Myr Prototype.\nMyr Prototype can't attack or block unless you pay {1} for each +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/r/rush_of_dread.txt b/forge-gui/res/cardsfolder/r/rush_of_dread.txt index db97c486165..35ce6863f2b 100644 --- a/forge-gui/res/cardsfolder/r/rush_of_dread.txt +++ b/forge-gui/res/cardsfolder/r/rush_of_dread.txt @@ -3,7 +3,7 @@ ManaCost:1 B B Types:Sorcery K:Spree A:SP$ Charm | Choices$ DBSacrifice,DBDiscard,DBLoseLife | MinCharmNum$ 1 | CharmNum$ 3 | Spree$ True -SVar:DBSacrifice:DB$ Sacrifice | SpreeCost$ 1 | ValidTgts$ Opponent | Amount$ Count$Valid Creature.ThisTargetedPlayerCtrl/HalfUp | SacValid$ Creature | Mode$ TgtChoose | SpellDescription$ Target opponent sacrifices half the creatures they control, rounded up. +SVar:DBSacrifice:DB$ Sacrifice | SpreeCost$ 1 | ValidTgts$ Opponent | Amount$ ThisTargetedPlayer$Valid Creature.YouCtrl/HalfUp | SacValid$ Creature | Mode$ TgtChoose | SpellDescription$ Target opponent sacrifices half the creatures they control, rounded up. SVar:DBDiscard:DB$ Discard | SpreeCost$ 1 | ValidTgts$ Opponent | NumCards$ ThisTargetedPlayer$CardsInHand/HalfUp | Mode$ TgtChoose | SpellDescription$ Target opponent discards half the cards in their hand, rounded up. SVar:DBLoseLife:DB$ LoseLife | SpreeCost$ 2 | ValidTgts$ Opponent | LifeAmount$ ThisTargetedPlayer$LifeTotal/HalfUp | SpellDescription$ Target opponent loses half their life, rounded up. Oracle:Spree (Choose one or more additional costs.)\n+ {1} — Target opponent sacrifices half the creatures they control, rounded up.\n+ {2} — Target opponent discards half the cards in their hand, rounded up.\n+ {2} — Target opponent loses half their life, rounded up. diff --git a/forge-gui/res/cardsfolder/s/skeleton_scavengers.txt b/forge-gui/res/cardsfolder/s/skeleton_scavengers.txt index 0e1133cbe02..6cf5efc02ad 100644 --- a/forge-gui/res/cardsfolder/s/skeleton_scavengers.txt +++ b/forge-gui/res/cardsfolder/s/skeleton_scavengers.txt @@ -3,9 +3,9 @@ ManaCost:2 B Types:Creature Skeleton PT:0/0 K:etbCounter:P1P1:1 -A:AB$ Regenerate | Cost$ X | CostDesc$ Pay {1} for each +1/+1 counter on CARDNAME: | RegenerationAbility$ DBImmediateTrigger | StackDescription$ SpellDescription | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a +1/+1 counter on it. +A:AB$ Regenerate | Cost$ Mana<1\NumTimes> | CostDesc$ Pay {1} for each +1/+1 counter on CARDNAME: | RegenerationAbility$ DBImmediateTrigger | StackDescription$ SpellDescription | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a +1/+1 counter on it. SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigPutCounter | TriggerDescription$ When it regenerates this way, put a +1/+1 counter on it. -SVar:TrigPutCounter:DB$ PutCounter | Defined$ EffectSource | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ When it regenerates this way, put a +1/+1 counter on it. -SVar:X:Count$CardCounters.P1P1 +SVar:TrigPutCounter:DB$ PutCounter | Defined$ EffectSource | CounterType$ P1P1 | CounterNum$ 1 +SVar:NumTimes:Count$CardCounters.P1P1 DeckHas:Ability$Counters Oracle:Skeleton Scavengers enters the battlefield with a +1/+1 counter on it.\nPay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/s/snakeskin_veil.txt b/forge-gui/res/cardsfolder/s/snakeskin_veil.txt index a53e77756cc..4c31fb3d03c 100644 --- a/forge-gui/res/cardsfolder/s/snakeskin_veil.txt +++ b/forge-gui/res/cardsfolder/s/snakeskin_veil.txt @@ -1,7 +1,7 @@ Name:Snakeskin Veil ManaCost:G Types:Instant -A:SP$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature. +A:SP$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature you control. SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Hexproof DeckHas:Ability$Counters Oracle:Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn. diff --git a/forge-gui/res/cardsfolder/w/war_cadence.txt b/forge-gui/res/cardsfolder/w/war_cadence.txt index be2378f982a..a6b52ca4ae6 100644 --- a/forge-gui/res/cardsfolder/w/war_cadence.txt +++ b/forge-gui/res/cardsfolder/w/war_cadence.txt @@ -1,11 +1,9 @@ Name:War Cadence ManaCost:2 R Types:Enchantment -A:AB$ StoreSVar | Cost$ X R | SVar$ PaidNum | Type$ Count | Expression$ xPaid | SubAbility$ CadenceEffect | AILogic$ RestrictBlocking | SpellDescription$ This turn, creatures can't block unless their controller pays {X} for each blocking creature they control. -SVar:CadenceEffect:DB$ Effect | StaticAbilities$ CadenceStaticAb | Stackable$ False | RememberObjects$ Valid Creature.blocking -SVar:CadenceStaticAb:Mode$ CantBlockUnless | ValidCard$ Card.IsNotRemembered | Cost$ PaidNum | EffectZone$ Command | Description$ This turn, creatures can't block unless their controller pays {X} for each blocking creature they control. +A:AB$ Effect | Cost$ X R | StaticAbilities$ CadenceStaticAb | Stackable$ False | SetChosenNumber$ X | AILogic$ RestrictBlocking | SpellDescription$ This turn, creatures can't block unless their controller pays {X} for each blocking creature they control. +SVar:CadenceStaticAb:Mode$ CantBlockUnless | Cost$ XChosen | EffectZone$ Command | Description$ This turn, creatures can't block unless their controller pays {X} for each blocking creature they control. SVar:X:Count$xPaid -SVar:PaidNum:Number$0 +SVar:XChosen:Count$ChosenNumber SVar:NonStackingEffect:True -AI:RemoveDeck:All Oracle:{X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature they control. diff --git a/forge-gui/res/cardsfolder/w/war_tax.txt b/forge-gui/res/cardsfolder/w/war_tax.txt index 31a85969bcb..b58dea9e8e7 100644 --- a/forge-gui/res/cardsfolder/w/war_tax.txt +++ b/forge-gui/res/cardsfolder/w/war_tax.txt @@ -1,11 +1,9 @@ Name:War Tax ManaCost:2 U Types:Enchantment -A:AB$ StoreSVar | SVar$ Y | Type$ Count | Expression$ xPaid | Cost$ X U | SubAbility$ DBEffect | SpellDescription$ This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control. -SVar:DBEffect:DB$ Effect | StaticAbilities$ AttackTax | SubAbility$ DBReset | EffectOwner$ SourceController -SVar:AttackTax:Mode$ CantAttackUnless | ValidCard$ Creature | EffectZone$ Command | Cost$ Y | Description$ Creatures can't attack unless their controller pays {X} for each attacking creature they control. -SVar:DBReset:DB$ StoreSVar | SVar$ Y | Type$ Number | Expression$ 0 +A:AB$ Effect | Cost$ X U | StaticAbilities$ AttackTax | SetChosenNumber$ X | SpellDescription$ This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control. +SVar:AttackTax:Mode$ CantAttackUnless | ValidCard$ Creature | EffectZone$ Command | Cost$ XChosen | Description$ Creatures can't attack unless their controller pays {X} for each attacking creature they control. SVar:X:Count$xPaid -SVar:Y:Number$0 +SVar:XChosen:Count$ChosenNumber AI:RemoveDeck:All Oracle:{X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control. diff --git a/forge-gui/res/cardsfolder/z/zimone_and_dina.txt b/forge-gui/res/cardsfolder/z/zimone_and_dina.txt index 02ae9eafb7c..589500f8b63 100644 --- a/forge-gui/res/cardsfolder/z/zimone_and_dina.txt +++ b/forge-gui/res/cardsfolder/z/zimone_and_dina.txt @@ -7,6 +7,6 @@ SVar:LoseGain:DB$ LoseLife | ValidTgts$ Opponent | LifeAmount$ 2 | SubAbility$ D SVar:DBGain:DB$ GainLife | Defined$ You | LifeAmount$ 2 A:AB$ Repeat | Cost$ T Sac<1/Creature.Other/another creature> | RepeatSubAbility$ DBDraw | MaxRepeat$ 2 | RepeatPresent$ Land.YouCtrl | RepeatCompare$ GE8 | StackDescription$ SpellDescription | SpellDescription$ Draw a card. You may put a land card from your hand onto the battlefield tapped. If you control eight or more lands, repeat this process once. SVar:DBDraw:DB$ Draw | SubAbility$ DBChangeZone -DeckHas:Ability$LifeGain|Sacrifice SVar:DBChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Optional$ You | ChangeType$ Land | ChangeNum$ 1 | Tapped$ True +DeckHas:Ability$LifeGain|Sacrifice Oracle:Whenever you draw your second card each turn, target opponent loses 2 life and you gain 2 life.\n{T}, Sacrifice another creature: Draw a card. You may put a land card from your hand onto the battlefield tapped. If you control eight or more lands, repeat this process once.