Fix X shards in combat tax missing from total cost (#5154)

This commit is contained in:
tool4ever
2024-04-25 09:32:42 +02:00
committed by GitHub
parent c20c214b9c
commit 7e828fd654
15 changed files with 74 additions and 83 deletions

View File

@@ -11,6 +11,7 @@ import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.card.*; import forge.game.card.*;
import forge.game.card.CardPredicates.Presets;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.combat.CombatUtil; import forge.game.combat.CombatUtil;
import forge.game.keyword.Keyword; import forge.game.keyword.Keyword;
@@ -30,6 +31,7 @@ import forge.util.MyRandom;
import forge.util.TextUtil; import forge.util.TextUtil;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -68,6 +70,41 @@ public class EffectAi extends SpellAbilityAi {
} }
randomReturn = true; 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<Card> possibleAttackers = ai.getCreaturesInPlay();
List<Card> possibleBlockers = opp.getCreaturesInPlay();
possibleBlockers = CardLists.filter(possibleBlockers, Presets.UNTAPPED);
final Combat combat = game.getCombat();
int oppLife = opp.getLife();
int potentialDmg = 0;
List<Card> 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")) { } else if (logic.equals("Fog")) {
FogAi fogAi = new FogAi(); FogAi fogAi = new FogAi();
if (!fogAi.canPlayAI(ai, sa)) { if (!fogAi.canPlayAI(ai, sa)) {

View File

@@ -1,18 +1,6 @@
package forge.ai.ability; package forge.ai.ability;
import java.util.ArrayList;
import java.util.List;
import forge.ai.ComputerUtilMana;
import forge.ai.SpellAbilityAi; 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.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.trigger.WrappedAbility; import forge.game.trigger.WrappedAbility;
@@ -21,51 +9,6 @@ public class StoreSVarAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { 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<Card> possibleAttackers = ai.getCreaturesInPlay();
List<Card> possibleBlockers = opp.getCreaturesInPlay();
possibleBlockers = CardLists.filter(possibleBlockers, Presets.UNTAPPED);
int oppLife = opp.getLife();
int potentialDmg = 0;
List<Card> 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; return true;
} }

View File

@@ -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 // 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()); final SpellAbility fakeSA = new SpellAbility.EmptySa(attacker, attacker.getController());
fakeSA.setCardState(attacker.getCurrentState()); 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, return attacker.getController().getController().payManaOptional(attacker, attackCost, fakeSA,
"Pay additional cost to declare " + attacker + " an attacker", ManaPaymentPurpose.DeclareAttacker); "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()); SpellAbility fakeSA = new SpellAbility.EmptySa(blocker, blocker.getController());
fakeSA.setCardState(blocker.getCurrentState()); 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); return blocker.getController().getController().payManaOptional(blocker, blockCost, fakeSA, "Pay cost to declare " + blocker + " a blocker. ", ManaPaymentPurpose.DeclareBlocker);
} }

View File

@@ -138,7 +138,7 @@ public class CostPartMana extends CostPart {
if (isCostPayAnyNumberOfTimes) { if (isCostPayAnyNumberOfTimes) {
int timesToPay = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getSVar("NumTimes"), sa); int timesToPay = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getSVar("NumTimes"), sa);
if (timesToPay == 0) { if (timesToPay == 0) {
return ManaCost.NO_COST; return ManaCost.ZERO;
} }
ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getMana()); ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getMana());
for (int i = 1; i < timesToPay; i++) { for (int i = 1; i < timesToPay; i++) {

View File

@@ -254,7 +254,12 @@ public class StaticAbilityCantAttackBlock {
if (remember) { if (remember) {
hostCard.addRemembered(attacker); hostCard.addRemembered(attacker);
} }
// keep X shards
boolean addX = costString.startsWith("X");
costString = Integer.toString(AbilityUtils.calculateAmount(hostCard, stAb.getSVar(costString), stAb)); costString = Integer.toString(AbilityUtils.calculateAmount(hostCard, stAb.getSVar(costString), stAb));
if (addX) {
costString += " X";
}
if (remember) { if (remember) {
hostCard.removeRemembered(attacker); hostCard.removeRemembered(attacker);
} }
@@ -288,7 +293,11 @@ public class StaticAbilityCantAttackBlock {
} }
String costString = stAb.getParam("Cost"); String costString = stAb.getParam("Cost");
if (stAb.hasSVar(costString)) { 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); return new Cost(costString, true);

View File

@@ -3,7 +3,7 @@ ManaCost:W
Types:Enchantment Aura Types:Enchantment Aura
K:Enchant creature K:Enchant creature
A:SP$ Attach | Cost$ W | ValidTgts$ Creature | AILogic$ Curse 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$ 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$ X S:Mode$ CantBlockUnless | ValidCard$ Creature.AttachedBy | Cost$ Y
SVar:X:Count$InYourHand 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. Oracle:Enchant creature\nEnchanted creature can't attack or block unless its controller pays {1} for each card in your hand.

View File

@@ -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:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Card | SubAbility$ DBInvestigate
SVar:DBInvestigate:DB$ Investigate 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. 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 SVar:HasAttackEffect:TRUE
DeckHas:Ability$Investigate|Token|Graveyard & Type$Artifact|Clue DeckHas:Ability$Investigate|Token|Graveyard & Type$Artifact|Clue
DeckHints:Ability$Graveyard DeckHints:Ability$Graveyard

View File

@@ -3,7 +3,7 @@ ManaCost:2 R
Types:Creature Human Rogue Types:Creature Human Rogue
PT:3/2 PT:3/2
K:Trample 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 SVar:TrigTreasure:DB$ Token | TokenScript$ c_a_treasure_sac
DeckHas:Ability$Token|Sacrifice & Type$Artifact|Treasure 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.") 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.")

View File

@@ -4,7 +4,7 @@ Types:Artifact Creature Myr
PT:2/2 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. 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 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$ 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$ X S:Mode$ CantBlockUnless | ValidCard$ Card.Self | Cost$ Y
SVar:X:Count$CardCounters.P1P1 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. 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.

View File

@@ -3,7 +3,7 @@ ManaCost:1 B B
Types:Sorcery Types:Sorcery
K:Spree K:Spree
A:SP$ Charm | Choices$ DBSacrifice,DBDiscard,DBLoseLife | MinCharmNum$ 1 | CharmNum$ 3 | Spree$ True 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: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. 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. 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.

View File

@@ -3,9 +3,9 @@ ManaCost:2 B
Types:Creature Skeleton Types:Creature Skeleton
PT:0/0 PT:0/0
K:etbCounter:P1P1:1 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: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:TrigPutCounter:DB$ PutCounter | Defined$ EffectSource | CounterType$ P1P1 | CounterNum$ 1
SVar:X:Count$CardCounters.P1P1 SVar:NumTimes:Count$CardCounters.P1P1
DeckHas:Ability$Counters 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. 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.

View File

@@ -1,7 +1,7 @@
Name:Snakeskin Veil Name:Snakeskin Veil
ManaCost:G ManaCost:G
Types:Instant 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 SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Hexproof
DeckHas:Ability$Counters DeckHas:Ability$Counters
Oracle:Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn. Oracle:Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.

View File

@@ -1,11 +1,9 @@
Name:War Cadence Name:War Cadence
ManaCost:2 R ManaCost:2 R
Types:Enchantment 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. 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:CadenceEffect:DB$ Effect | StaticAbilities$ CadenceStaticAb | Stackable$ False | RememberObjects$ Valid Creature.blocking 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: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.
SVar:X:Count$xPaid SVar:X:Count$xPaid
SVar:PaidNum:Number$0 SVar:XChosen:Count$ChosenNumber
SVar:NonStackingEffect:True 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. Oracle:{X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature they control.

View File

@@ -1,11 +1,9 @@
Name:War Tax Name:War Tax
ManaCost:2 U ManaCost:2 U
Types:Enchantment 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. 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:DBEffect:DB$ Effect | StaticAbilities$ AttackTax | SubAbility$ DBReset | EffectOwner$ SourceController 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: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
SVar:X:Count$xPaid SVar:X:Count$xPaid
SVar:Y:Number$0 SVar:XChosen:Count$ChosenNumber
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:{X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control. Oracle:{X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control.

View File

@@ -7,6 +7,6 @@ SVar:LoseGain:DB$ LoseLife | ValidTgts$ Opponent | LifeAmount$ 2 | SubAbility$ D
SVar:DBGain:DB$ GainLife | Defined$ You | LifeAmount$ 2 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. 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 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 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. 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.