mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
@@ -46,6 +46,7 @@ import forge.game.combat.GlobalAttackRestrictions;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerCollection;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityPredicates;
|
||||
import forge.game.trigger.Trigger;
|
||||
@@ -71,7 +72,7 @@ public class AiAttackController {
|
||||
|
||||
// possible attackers and blockers
|
||||
private List<Card> attackers;
|
||||
private final List<Card> blockers;
|
||||
private List<Card> blockers;
|
||||
|
||||
private List<Card> oppList; // holds human player creatures
|
||||
private List<Card> myList; // holds computer creatures
|
||||
@@ -95,11 +96,9 @@ public class AiAttackController {
|
||||
public AiAttackController(final Player ai, boolean nextTurn) {
|
||||
this.ai = ai;
|
||||
defendingOpponent = choosePreferredDefenderPlayer(ai);
|
||||
this.oppList = getOpponentCreatures(defendingOpponent);
|
||||
myList = ai.getCreaturesInPlay();
|
||||
this.nextTurn = nextTurn;
|
||||
refreshAttackers(defendingOpponent);
|
||||
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
|
||||
refreshCombatants(defendingOpponent);
|
||||
} // overloaded constructor to evaluate attackers that should attack next turn
|
||||
|
||||
public AiAttackController(final Player ai, Card attacker) {
|
||||
@@ -115,13 +114,15 @@ public class AiAttackController {
|
||||
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
|
||||
} // overloaded constructor to evaluate single specified attacker
|
||||
|
||||
private void refreshAttackers(GameEntity defender) {
|
||||
private void refreshCombatants(GameEntity defender) {
|
||||
this.oppList = getOpponentCreatures(defendingOpponent);
|
||||
this.attackers = new ArrayList<>();
|
||||
for (Card c : myList) {
|
||||
if (canAttackWrapper(c, defender)) {
|
||||
attackers.add(c);
|
||||
}
|
||||
}
|
||||
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
|
||||
}
|
||||
|
||||
public static List<Card> getOpponentCreatures(final Player defender) {
|
||||
@@ -149,6 +150,7 @@ public class AiAttackController {
|
||||
|
||||
public void removeBlocker(Card blocker) {
|
||||
this.oppList.remove(blocker);
|
||||
this.blockers.remove(blocker);
|
||||
}
|
||||
|
||||
private boolean canAttackWrapper(final Card attacker, final GameEntity defender) {
|
||||
@@ -708,12 +710,24 @@ public class AiAttackController {
|
||||
* @return a {@link forge.game.combat.Combat} object.
|
||||
*/
|
||||
public final int declareAttackers(final Combat combat) {
|
||||
// something prevents attacking, try another
|
||||
if (this.attackers.isEmpty() && ai.getOpponents().size() > 1) {
|
||||
final PlayerCollection opps = ai.getOpponents();
|
||||
opps.remove(defendingOpponent);
|
||||
defendingOpponent = Aggregates.random(opps);
|
||||
refreshCombatants(defendingOpponent);
|
||||
}
|
||||
|
||||
final boolean bAssault = doAssault();
|
||||
|
||||
// Determine who will be attacked
|
||||
GameEntity defender = chooseDefender(combat, bAssault);
|
||||
|
||||
// decided to attack another defender so related lists need to be updated
|
||||
// (though usually rather try to avoid this situation for performance reasons)
|
||||
if (defender != defendingOpponent) {
|
||||
refreshAttackers(defender);
|
||||
defendingOpponent = defender instanceof Player ? (Player) defender : ((Card)defender).getController();
|
||||
refreshCombatants(defender);
|
||||
}
|
||||
if (this.attackers.isEmpty()) {
|
||||
return aiAggression;
|
||||
@@ -910,8 +924,6 @@ public class AiAttackController {
|
||||
final List<Card> nextTurnAttackers = new ArrayList<>();
|
||||
int candidateCounterAttackDamage = 0;
|
||||
|
||||
final Player opp = defender instanceof Player ? (Player) defender : ((Card)defender).getController();
|
||||
this.oppList = getOpponentCreatures(opp);
|
||||
// get the potential damage and strength of the AI forces
|
||||
final List<Card> candidateAttackers = new ArrayList<>();
|
||||
int candidateUnblockedDamage = 0;
|
||||
@@ -920,7 +932,7 @@ public class AiAttackController {
|
||||
// turn, assume summoning sickness creatures will be able to
|
||||
if (ComputerUtilCombat.canAttackNextTurn(pCard) && pCard.getNetCombatDamage() > 0) {
|
||||
candidateAttackers.add(pCard);
|
||||
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null, false);
|
||||
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, defendingOpponent, null, false);
|
||||
computerForces++;
|
||||
}
|
||||
}
|
||||
@@ -962,7 +974,7 @@ public class AiAttackController {
|
||||
// find the potential damage ratio the AI can cause
|
||||
double humanLifeToDamageRatio = 1000000;
|
||||
if (candidateUnblockedDamage > 0) {
|
||||
humanLifeToDamageRatio = (double) (opp.getLife() - ComputerUtil.possibleNonCombatDamage(ai, opp)) / candidateUnblockedDamage;
|
||||
humanLifeToDamageRatio = (double) (defendingOpponent.getLife() - ComputerUtil.possibleNonCombatDamage(ai, defendingOpponent)) / candidateUnblockedDamage;
|
||||
}
|
||||
|
||||
// determine if the ai outnumbers the player
|
||||
@@ -987,7 +999,7 @@ public class AiAttackController {
|
||||
// get list of attackers ordered from low power to high
|
||||
CardLists.sortByPowerAsc(this.attackers);
|
||||
// get player life total
|
||||
int humanLife = opp.getLife();
|
||||
int humanLife = defendingOpponent.getLife();
|
||||
// get the list of attackers up to the first blocked one
|
||||
final List<Card> attritionalAttackers = new ArrayList<>();
|
||||
for (int x = 0; x < (this.attackers.size() - humanForces); x++) {
|
||||
@@ -1037,7 +1049,7 @@ public class AiAttackController {
|
||||
}
|
||||
}
|
||||
if (isUnblockableCreature) {
|
||||
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat, false);
|
||||
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, defendingOpponent, combat, false);
|
||||
}
|
||||
}
|
||||
for (final Card attacker : nextTurnAttackers) {
|
||||
@@ -1051,13 +1063,13 @@ public class AiAttackController {
|
||||
}
|
||||
}
|
||||
if (isUnblockableCreature) {
|
||||
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null, false);
|
||||
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, defendingOpponent, null, false);
|
||||
}
|
||||
}
|
||||
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife() && opp.canLoseLife()) {
|
||||
turnsUntilDeathByUnblockable = 1 + (opp.getLife() - unblockableDamage) / nextUnblockableDamage;
|
||||
if (unblockableDamage > 0 && !defendingOpponent.cantLoseForZeroOrLessLife() && defendingOpponent.canLoseLife()) {
|
||||
turnsUntilDeathByUnblockable = 1 + (defendingOpponent.getLife() - unblockableDamage) / nextUnblockableDamage;
|
||||
}
|
||||
if (opp.canLoseLife()) {
|
||||
if (defendingOpponent.canLoseLife()) {
|
||||
doUnblockableAttack = true;
|
||||
}
|
||||
// *****************
|
||||
@@ -1114,8 +1126,8 @@ public class AiAttackController {
|
||||
if ( LOG_AI_ATTACKS )
|
||||
System.out.println("attackersLeft = " + attackersLeft);
|
||||
|
||||
FCollection<GameEntity> possibleDefenders = new FCollection<>(opp);
|
||||
possibleDefenders.addAll(opp.getPlaneswalkersInPlay());
|
||||
FCollection<GameEntity> possibleDefenders = new FCollection<>(defendingOpponent);
|
||||
possibleDefenders.addAll(defendingOpponent.getPlaneswalkersInPlay());
|
||||
|
||||
while (!attackersLeft.isEmpty()) {
|
||||
CardCollection attackersAssigned = new CardCollection();
|
||||
@@ -1164,7 +1176,7 @@ public class AiAttackController {
|
||||
if (pwDefending.isEmpty()) {
|
||||
// TODO for now only looks at same player as we'd have to check the others from start too
|
||||
//defender = new PlayerCollection(Iterables.filter(possibleDefenders, Player.class)).min(PlayerPredicates.compareByLife());
|
||||
defender = opp;
|
||||
defender = defendingOpponent;
|
||||
} else {
|
||||
final Card pwNearUlti = ComputerUtilCard.getBestPlaneswalkerToDamage(pwDefending);
|
||||
defender = pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending);
|
||||
|
||||
@@ -88,6 +88,13 @@ public class AiController {
|
||||
private SpellAbilityPicker simPicker;
|
||||
private int lastAttackAggression;
|
||||
|
||||
public AiController(final Player computerPlayer, final Game game0) {
|
||||
player = computerPlayer;
|
||||
game = game0;
|
||||
memory = new AiCardMemory();
|
||||
simPicker = new SpellAbilityPicker(game, player);
|
||||
}
|
||||
|
||||
public boolean canCheatShuffle() {
|
||||
return cheatShuffle;
|
||||
}
|
||||
@@ -141,13 +148,6 @@ public class AiController {
|
||||
return predictedCombatNextTurn;
|
||||
}
|
||||
|
||||
public AiController(final Player computerPlayer, final Game game0) {
|
||||
player = computerPlayer;
|
||||
game = game0;
|
||||
memory = new AiCardMemory();
|
||||
simPicker = new SpellAbilityPicker(game, player);
|
||||
}
|
||||
|
||||
private List<SpellAbility> getPossibleETBCounters() {
|
||||
CardCollection all = new CardCollection(player.getCardsIn(ZoneType.Hand));
|
||||
CardCollectionView ccvPlayerLibrary = player.getCardsIn(ZoneType.Library);
|
||||
|
||||
@@ -341,7 +341,7 @@ public class CountersPutAi extends CountersAi {
|
||||
|
||||
if (sa.hasParam("Bolster")) {
|
||||
CardCollection creatsYouCtrl = ai.getCreaturesInPlay();
|
||||
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
|
||||
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness));
|
||||
if (leastToughness.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2347,9 +2347,6 @@ public class AbilityUtils {
|
||||
if (sq[0].equals("BloodthirstAmount")) {
|
||||
return doXMath(player.getBloodthirstAmount(), expr, c, ctb);
|
||||
}
|
||||
if (sq[0].equals("YourLandsPlayed")) {
|
||||
return doXMath(player.getLandsPlayedThisTurn(), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("YourCounters")) {
|
||||
// "YourCountersExperience" or "YourCountersPoison"
|
||||
@@ -2835,16 +2832,10 @@ public class AbilityUtils {
|
||||
return Aggregates.max(list, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
if (sq[0].startsWith("DifferentPower_")) {
|
||||
final List<Integer> powers = Lists.newArrayList();
|
||||
final String restriction = l[0].substring(15);
|
||||
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, player, c, ctb);
|
||||
for (final Card card : list) {
|
||||
Integer pow = card.getNetPower();
|
||||
if (!powers.contains(pow)) {
|
||||
powers.add(pow);
|
||||
}
|
||||
}
|
||||
return doXMath(powers.size(), expr, c, ctb);
|
||||
final Iterable<Card> powers = Aggregates.uniqueByLast(list, CardPredicates.Accessors.fnGetNetPower);
|
||||
return doXMath(Iterables.size(powers), expr, c, ctb);
|
||||
}
|
||||
if (sq[0].startsWith("DifferentCounterKinds_")) {
|
||||
final List<CounterType> kinds = Lists.newArrayList();
|
||||
|
||||
@@ -183,7 +183,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("Bolster")) {
|
||||
CardCollection creatsYouCtrl = activator.getCreaturesInPlay();
|
||||
CardCollection leastToughness = new CardCollection(
|
||||
Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
|
||||
Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness));
|
||||
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("CounterType", counterType);
|
||||
|
||||
@@ -733,13 +733,6 @@ public final class CardPredicates {
|
||||
}
|
||||
|
||||
public static class Accessors {
|
||||
public static final Function<Card, Integer> fnGetDefense = new Function<Card, Integer>() {
|
||||
@Override
|
||||
public Integer apply(Card a) {
|
||||
return a.getNetToughness();
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function<Card, Integer> fnGetNetPower = new Function<Card, Integer>() {
|
||||
@Override
|
||||
public Integer apply(Card a) {
|
||||
|
||||
@@ -268,7 +268,7 @@ public class CombatUtil {
|
||||
}
|
||||
|
||||
return true;
|
||||
} // canAttack(Card, GameEntity)
|
||||
}
|
||||
|
||||
public static boolean isAttackerSick(final Card attacker, final GameEntity defender) {
|
||||
final Game game = attacker.getGame();
|
||||
@@ -1158,7 +1158,7 @@ public class CombatUtil {
|
||||
}
|
||||
|
||||
return true;
|
||||
} // canBlock()
|
||||
}
|
||||
|
||||
public static boolean canAttackerBeBlockedWithAmount(Card attacker, int amount, Combat combat) {
|
||||
return canAttackerBeBlockedWithAmount(attacker, amount, combat != null ? combat.getDefenderPlayerByAttacker(attacker) : null);
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Orc Shaman
|
||||
PT:2/2
|
||||
K:Dash:3 B
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.Self,Creature.YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, that creature gets +2/+2.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | NumDef$ +2
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | NumDef$ +2
|
||||
SVar:BuffedBy:Creature
|
||||
Oracle:Whenever Ambuscade Shaman or another creature enters the battlefield under your control, that creature gets +2/+2 until end of turn.\nDash {3}{B} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)
|
||||
|
||||
@@ -3,6 +3,5 @@ ManaCost:2 W
|
||||
Types:Creature Kor Wizard
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, you and target opponent each draw a card.
|
||||
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | NumCards$ 1 | SubAbility$ DBDraw
|
||||
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1
|
||||
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | Defined$ TargetedAndYou | NumCards$ 1
|
||||
Oracle:When Farsight Adept enters the battlefield, you and target opponent each draw a card.
|
||||
|
||||
@@ -5,6 +5,5 @@ PT:0/4
|
||||
K:Defender
|
||||
K:Flying
|
||||
T:Mode$ DamageDoneOnce | Execute$ TrigDraw | ValidTarget$ Card.Self | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME is dealt damage, you and target opponent each draw a card.
|
||||
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | NumCards$ 1 | SubAbility$ DBDraw
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
||||
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | Defined$ TargetedAndYou | NumCards$ 1
|
||||
Oracle:Defender, flying\nWhenever Flumph is dealt damage, you and target opponent each draw a card.
|
||||
|
||||
@@ -2,6 +2,6 @@ Name:In the Web of War
|
||||
ManaCost:3 R R
|
||||
Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever a creature enters the battlefield under your control, it gets +2/+0 and gains haste until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | KW$ Haste
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | KW$ Haste
|
||||
SVar:BuffedBy:Creature
|
||||
Oracle:Whenever a creature enters the battlefield under your control, it gets +2/+0 and gains haste until end of turn.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Dinosaur
|
||||
PT:2/3
|
||||
S:Mode$ ReduceCost | ValidCard$ Creature | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Creature spells you cast cost {1} less to cast.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever another creature enters the battlefield under your control, CARDNAME deals 2 damage to it. If a Dinosaur is dealt damage this way, CARDNAME gets +2/+0 until end of turn.
|
||||
SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredCard | NumDmg$ 2 | RememberDamaged$ True | SubAbility$ DBPump
|
||||
SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredCardLKICopy | NumDmg$ 2 | RememberDamaged$ True | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ Self | NumAtt$ 2 | ConditionDefined$ Remembered | ConditionPresent$ Creature.Dinosaur | ConditionCompare$ EQ1 | ConditionDescription$ If a Dinosaur is dealt damage this way, CARDNAME gets +2/+0 until end of turn. | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
AI:RemoveDeck:All
|
||||
|
||||
@@ -3,5 +3,5 @@ ManaCost:5
|
||||
Types:Artifact
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ AtlasDraw | CheckSVar$ X | SVarCompare$ EQ0 | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, if you didn't play a land this turn, you may draw a card.
|
||||
SVar:AtlasDraw:DB$ Draw | Defined$ You | NumCards$ 1
|
||||
SVar:X:Count$YourLandsPlayed
|
||||
SVar:X:PlayerCountPropertyYou$LandsPlayed
|
||||
Oracle:At the beginning of your end step, if you didn't play a land this turn, you may draw a card.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:2 R R
|
||||
Types:Creature Ogre Warrior
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever another creature enters the battlefield under your control, that creature gets +2/+0 and haste until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | NumDef$ +0 | KW$ Haste
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | NumDef$ +0 | KW$ Haste
|
||||
SVar:BuffedBy:Creature
|
||||
Oracle:Whenever another creature enters the battlefield under your control, that creature gets +2/+0 and gains haste until end of turn. (It can attack and {T} this turn.)
|
||||
|
||||
@@ -5,5 +5,5 @@ A:AB$ Mana | Cost$ T | Produced$ U | ConditionCheckSVar$ X | ConditionSVarCompar
|
||||
SVar:ManaB:DB$ Mana | Produced$ B | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1
|
||||
AI:RemoveDeck:Random
|
||||
DeckHints:Color$Blue|Black
|
||||
SVar:X:Count$YourLandsPlayed
|
||||
SVar:X:PlayerCountPropertyYou$LandsPlayed
|
||||
Oracle:{T}: Add {U}. If you played a land this turn, add {B} instead.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Goblin
|
||||
PT:3/3
|
||||
S:Mode$ CantBeCast | Caster$ You | ValidCard$ Card.Self | CheckSVar$ XJockey | SVarCompare$ GE1 | EffectZone$ All | Description$ You can't cast this spell if you've played a land this turn.
|
||||
S:Mode$ CantPlayLand | Player$ You | CheckSVar$ RockyX | SVarCompare$ GE1 | Description$ You can't play lands if you've cast CARDNAME this turn.
|
||||
SVar:XJockey:Count$YourLandsPlayed
|
||||
SVar:XJockey:PlayerCountPropertyYou$LandsPlayed
|
||||
SVar:RockyX:Count$ThisTurnCast_Card.Self
|
||||
Oracle:You can't cast this spell if you've played a land this turn.\nYou can't play lands if you've cast Rock Jockey this turn.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Name:Secret Rendezvous
|
||||
ManaCost:1 W W
|
||||
Types:Sorcery
|
||||
A:SP$ Draw | Cost$ 1 W W | NumCards$ 3 | SubAbility$ DBDraw | SpellDescription$ You and target opponent each draw three cards.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 3 | ValidTgts$ Opponent | TgtPrompt$ Select target opponent
|
||||
A:SP$ Draw | Cost$ 1 W W | NumCards$ 3 | ValidTgts$ Opponent | Defined$ TargetedAndYou | SpellDescription$ You and target opponent each draw three cards.
|
||||
Oracle:You and target opponent each draw three cards.
|
||||
|
||||
@@ -5,9 +5,9 @@ PT:2/4
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, put a shield counter on target creature an opponent controls.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | CounterType$ SHIELD | AILogic$ Curse
|
||||
T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouDontCtrl | ValidSource$ You | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever you put one or more counters on a creature you don't control, tap that creature and goad it. It gains trample until your next turn. (Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)
|
||||
SVar:TrigTap:DB$ Tap | Defined$ TriggeredCard | SubAbility$ DBGoad
|
||||
SVar:DBGoad:DB$ Goad | Defined$ TriggeredCard | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ TriggeredCard | KW$ Trample | Duration$ UntilYourNextTurn
|
||||
SVar:TrigTap:DB$ Tap | Defined$ TriggeredCardLKICopy | SubAbility$ DBGoad
|
||||
SVar:DBGoad:DB$ Goad | Defined$ TriggeredCardLKICopy | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ TriggeredCardLKICopy | KW$ Trample | Duration$ UntilYourNextTurn
|
||||
#Card doesn't make sense to run unless you have 2 or more opponents
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:At the beginning of your upkeep, put a shield counter on target creature an opponent controls.\nWhenever you put one or more counters on a creature you don't control, tap that creature and goad it. It gains trample until your next turn. (Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)
|
||||
|
||||
@@ -6,5 +6,5 @@ K:Trample
|
||||
T:Mode$ TapsForMana | ValidCard$ Land | Activator$ You | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever you tap a land for mana, add one mana of any type that land produced.
|
||||
SVar:TrigMana:DB$ ManaReflected | ColorOrType$ Type | ReflectProperty$ Produced | Defined$ You
|
||||
T:Mode$ TapsForMana | ValidCard$ Land.OppCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent taps a land for mana, that land doesn't untap during its controller's next untap step.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | Duration$ Permanent | KW$ HIDDEN This card doesn't untap during your next untap step.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | Duration$ Permanent | KW$ HIDDEN This card doesn't untap during your next untap step.
|
||||
Oracle:Trample\nWhenever you tap a land for mana, add one mana of any type that land produced.\nWhenever an opponent taps a land for mana, that land doesn't untap during its controller's next untap step.
|
||||
|
||||
Reference in New Issue
Block a user