mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Merge pull request #3018 from tool4ever/battlefix
Fix some crashes with Battles
This commit is contained in:
@@ -722,6 +722,11 @@ public class AiAttackController {
|
||||
return pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending);
|
||||
}
|
||||
|
||||
List<Card> battleDefending = c.getDefendingBattles();
|
||||
if (!battleDefending.isEmpty()) {
|
||||
// TODO filter for team ones
|
||||
}
|
||||
|
||||
return prefDefender;
|
||||
}
|
||||
|
||||
|
||||
@@ -2059,31 +2059,23 @@ public class ComputerUtilCombat {
|
||||
|
||||
if (block.size() == 1) {
|
||||
final Card blocker = block.getFirst();
|
||||
int dmgToBlocker = dmgCanDeal;
|
||||
|
||||
if (hasTrample) {
|
||||
int dmgToKill = getEnoughDamageToKill(blocker, dmgCanDeal, attacker, true);
|
||||
if (hasTrample && isAttacking) { // otherwise no entity to deliver damage via trample
|
||||
dmgToBlocker = getEnoughDamageToKill(blocker, dmgCanDeal, attacker, true);
|
||||
|
||||
if (dmgCanDeal < dmgToKill) {
|
||||
dmgToKill = Math.min(blocker.getLethalDamage(), dmgCanDeal);
|
||||
} else {
|
||||
dmgToKill = Math.max(blocker.getLethalDamage(), dmgToKill);
|
||||
if (dmgCanDeal < dmgToBlocker) {
|
||||
// can't kill so just put the lowest legal amount
|
||||
dmgToBlocker = Math.min(blocker.getLethalDamage(), dmgCanDeal);
|
||||
}
|
||||
|
||||
if (!isAttacking) { // no entity to deliver damage via trample
|
||||
dmgToKill = dmgCanDeal;
|
||||
}
|
||||
|
||||
final int remainingDmg = dmgCanDeal - dmgToKill;
|
||||
|
||||
final int remainingDmg = dmgCanDeal - dmgToBlocker;
|
||||
// If Extra trample damage, assign to defending player/planeswalker (when there is one)
|
||||
if (remainingDmg > 0) {
|
||||
damageMap.put(null, remainingDmg);
|
||||
}
|
||||
|
||||
damageMap.put(blocker, dmgToKill);
|
||||
} else {
|
||||
damageMap.put(blocker, dmgCanDeal);
|
||||
}
|
||||
damageMap.put(blocker, dmgToBlocker);
|
||||
} // 1 blocker
|
||||
else {
|
||||
// Does the attacker deal lethal damage to all blockers
|
||||
@@ -2478,10 +2470,15 @@ public class ComputerUtilCombat {
|
||||
public static GameEntity addAttackerToCombat(SpellAbility sa, Card attacker, Iterable<? extends GameEntity> defenders) {
|
||||
Combat combat = sa.getHostCard().getGame().getCombat();
|
||||
if (combat != null) {
|
||||
// 1. If the card that spawned the attacker was sent at a planeswalker, attack the same. Consider improving.
|
||||
GameEntity def = combat.getDefenderByAttacker(sa.getHostCard());
|
||||
if (def instanceof Card && ((Card)def).isPlaneswalker() && Iterables.contains(defenders, def)) {
|
||||
return def;
|
||||
// 1. If the card that spawned the attacker was sent at a card, attack the same. Consider improving.
|
||||
if (def instanceof Card && Iterables.contains(defenders, def)) {
|
||||
if (((Card)def).isPlaneswalker()) {
|
||||
return def;
|
||||
}
|
||||
if (((Card)def).isBattle()) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
// 2. Otherwise, go through the list of options one by one, choose the first one that can't be blocked profitably.
|
||||
for (GameEntity p : defenders) {
|
||||
|
||||
@@ -314,21 +314,21 @@ public abstract class SpellAbilityAi {
|
||||
public <T extends GameEntity> T chooseSingleEntity(Player ai, SpellAbility sa, Collection<T> options, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
|
||||
boolean hasPlayer = false;
|
||||
boolean hasCard = false;
|
||||
boolean hasPlaneswalker = false;
|
||||
boolean hasAttackableCard = false;
|
||||
|
||||
for (T ent : options) {
|
||||
if (ent instanceof Player) {
|
||||
hasPlayer = true;
|
||||
} else if (ent instanceof Card) {
|
||||
hasCard = true;
|
||||
if (((Card)ent).isPlaneswalker()) {
|
||||
hasPlaneswalker = true;
|
||||
if (((Card)ent).isPlaneswalker() || ((Card)ent).isBattle()) {
|
||||
hasAttackableCard = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPlayer && hasPlaneswalker) {
|
||||
return (T) chooseSinglePlayerOrPlaneswalker(ai, sa, (Collection<GameEntity>) options, params);
|
||||
if (hasPlayer && hasAttackableCard) {
|
||||
return (T) chooseSingleAttackableEntity(ai, sa, (Collection<GameEntity>) options, params);
|
||||
} else if (hasCard) {
|
||||
return (T) chooseSingleCard(ai, sa, (Collection<Card>) options, isOptional, targetedPlayer, params);
|
||||
} else if (hasPlayer) {
|
||||
@@ -353,7 +353,7 @@ public abstract class SpellAbilityAi {
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
|
||||
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
protected GameEntity chooseSingleAttackableEntity(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
System.err.println("Warning: default (ie. inherited from base class) implementation of chooseSinglePlayerOrPlaneswalker is used for " + this.getClass().getName() + ". Consider declaring an overloaded method");
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
|
||||
@@ -1760,12 +1760,12 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
protected GameEntity chooseSingleAttackableEntity(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
if (params != null && params.containsKey("Attacker")) {
|
||||
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
|
||||
}
|
||||
// should not be reached
|
||||
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);
|
||||
return super.chooseSingleAttackableEntity(ai, sa, options, params);
|
||||
}
|
||||
|
||||
private boolean doSacAndReturnFromGraveLogic(final Player ai, final SpellAbility sa) {
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.google.common.collect.Lists;
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerCollection;
|
||||
import forge.game.player.PlayerPredicates;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -31,7 +33,10 @@ public class ChoosePlayerAi extends SpellAbilityAi {
|
||||
@Override
|
||||
public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> choices, Map<String, Object> params) {
|
||||
Player chosen = null;
|
||||
if ("Curse".equals(sa.getParam("AILogic"))) {
|
||||
if (sa.hasParam("Protect")) {
|
||||
chosen = new PlayerCollection(choices).min(PlayerPredicates.compareByLife());
|
||||
}
|
||||
else if ("Curse".equals(sa.getParam("AILogic"))) {
|
||||
for (Player pc : choices) {
|
||||
if (pc.isOpponentOf(ai)) {
|
||||
chosen = pc;
|
||||
|
||||
@@ -261,12 +261,12 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
protected GameEntity chooseSingleAttackableEntity(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
if (params != null && params.containsKey("Attacker")) {
|
||||
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
|
||||
}
|
||||
// should not be reached
|
||||
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);
|
||||
return super.chooseSingleAttackableEntity(ai, sa, options, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -196,12 +196,12 @@ public class DigAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
protected GameEntity chooseSingleAttackableEntity(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
if (params != null && params.containsKey("Attacker")) {
|
||||
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
|
||||
}
|
||||
// should not be reached
|
||||
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);
|
||||
return super.chooseSingleAttackableEntity(ai, sa, options, params);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -326,12 +326,12 @@ public class TokenAi extends SpellAbilityAi {
|
||||
* @see forge.card.ability.SpellAbilityAi#chooseSinglePlayerOrPlaneswalker(forge.game.player.Player, forge.card.spellability.SpellAbility, Iterable<forge.game.GameEntity> options)
|
||||
*/
|
||||
@Override
|
||||
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
protected GameEntity chooseSingleAttackableEntity(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
|
||||
if (params != null && params.containsKey("Attacker")) {
|
||||
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
|
||||
}
|
||||
// should not be reached
|
||||
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);
|
||||
return super.chooseSingleAttackableEntity(ai, sa, options, params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1448,7 +1448,9 @@ public class GameAction {
|
||||
if (game.getCombat() != null) {
|
||||
game.getCombat().removeAbsentCombatants();
|
||||
}
|
||||
|
||||
table.triggerChangesZoneAll(game, null);
|
||||
|
||||
if (!checkAgain) {
|
||||
break; // do not continue the loop
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -54,6 +55,24 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
private static String generatedReflectedMana(final SpellAbility sa, final Collection<String> colors, final Player player) {
|
||||
// Calculate generated mana here for stack description and resolving
|
||||
final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa) : 1;
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (sa.getManaPart().isComboMana()) {
|
||||
Map<Byte, Integer> choices = player.getController().specifyManaCombo(sa, ColorSet.fromNames(colors), amount, false);
|
||||
for (Map.Entry<Byte, Integer> e : choices.entrySet()) {
|
||||
Byte chosenColor = e.getKey();
|
||||
String choice = MagicColor.toShortString(chosenColor);
|
||||
Integer count = e.getValue();
|
||||
while (count > 0) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(choice);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String baseMana;
|
||||
|
||||
@@ -93,7 +112,6 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (amount == 0) {
|
||||
sb.append("0");
|
||||
} else {
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardZoneTable;
|
||||
import forge.game.cost.Cost;
|
||||
@@ -109,13 +110,13 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
CardCollection tgtCards;
|
||||
CardCollection showCards = new CardCollection();
|
||||
CardCollectionView showCards = new CardCollection();
|
||||
|
||||
if (sa.hasParam("Valid")) {
|
||||
List<ZoneType> zones = sa.hasParam("ValidZone") ? ZoneType.listValueOf(sa.getParam("ValidZone")) : ImmutableList.of(ZoneType.Hand);
|
||||
tgtCards = new CardCollection(AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("Valid"), sa));
|
||||
if (sa.hasParam("ShowCards")) {
|
||||
showCards = new CardCollection(AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("ShowCards"), sa));
|
||||
showCards = AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("ShowCards"), sa);
|
||||
}
|
||||
} else if (sa.hasParam("AnySupportedCard")) {
|
||||
final String valid = sa.getParam("AnySupportedCard");
|
||||
|
||||
@@ -3180,7 +3180,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|
||||
// no Ability for this type yet, make a new one
|
||||
if (sa == null) {
|
||||
sa = CardFactoryUtil.buildBasicLandAbility(state, c);
|
||||
sa = CardFactory.buildBasicLandAbility(state, c);
|
||||
basicLandAbilities[i] = sa;
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,15 @@ public class CardFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public static SpellAbility buildBasicLandAbility(final CardState state, byte color) {
|
||||
String strcolor = MagicColor.toShortString(color);
|
||||
String abString = "AB$ Mana | Cost$ T | Produced$ " + strcolor +
|
||||
" | Secondary$ True | SpellDescription$ Add {" + strcolor + "}.";
|
||||
SpellAbility sa = AbilityFactory.getAbility(abString, state);
|
||||
sa.setIntrinsic(true); // always intrisic
|
||||
return sa;
|
||||
}
|
||||
|
||||
private static Card readCard(final CardRules rules, final IPaperCard paperCard, int cardId, Game game) {
|
||||
final Card card = new Card(cardId, paperCard, game);
|
||||
|
||||
|
||||
@@ -89,15 +89,6 @@ import io.sentry.Sentry;
|
||||
*/
|
||||
public class CardFactoryUtil {
|
||||
|
||||
public static SpellAbility buildBasicLandAbility(final CardState state, byte color) {
|
||||
String strcolor = MagicColor.toShortString(color);
|
||||
String abString = "AB$ Mana | Cost$ T | Produced$ " + strcolor +
|
||||
" | Secondary$ True | SpellDescription$ Add {" + strcolor + "}.";
|
||||
SpellAbility sa = AbilityFactory.getAbility(abString, state);
|
||||
sa.setIntrinsic(true); // always intrisic
|
||||
return sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* abilityMorphDown.
|
||||
@@ -3932,7 +3923,7 @@ public class CardFactoryUtil {
|
||||
StringBuilder chooseSB = new StringBuilder();
|
||||
chooseSB.append("Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated");
|
||||
chooseSB.append(" | Description$ (As a Siege enters the battlefield, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)");
|
||||
String chooseProtector = "DB$ ChoosePlayer | Defined$ You | Choices$ Opponent | Protect$ True | ChoiceTitle$ Choose an opponent to protect this battle | AILogic$ Curse";
|
||||
String chooseProtector = "DB$ ChoosePlayer | Defined$ You | Choices$ Opponent | Protect$ True | ChoiceTitle$ Choose an opponent to protect this battle";
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(chooseSB.toString(), card, true);
|
||||
re.setOverridingAbility(AbilityFactory.getAbility(chooseProtector, card));
|
||||
|
||||
@@ -203,7 +203,7 @@ public final class CardUtil {
|
||||
newCopy.getCurrentState().copyFrom(in.getState(in.getFaceupCardStateName()), true);
|
||||
if (in.isFaceDown()) {
|
||||
newCopy.turnFaceDownNoUpdate();
|
||||
newCopy.setType(new CardType(in.getCurrentState().getType()));
|
||||
newCopy.setType(new CardType(in.getFaceDownState().getType()));
|
||||
// prevent StackDescription from revealing face
|
||||
newCopy.updateStateForView();
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardDamageMap;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.player.Player;
|
||||
@@ -231,7 +233,11 @@ public class Combat {
|
||||
}
|
||||
|
||||
public final CardCollection getDefendingPlaneswalkers() {
|
||||
return new CardCollection(Iterables.filter(attackableEntries, Card.class));
|
||||
return CardLists.filter(Iterables.filter(attackableEntries, Card.class), CardPredicates.isType("Planeswalker"));
|
||||
}
|
||||
|
||||
public final CardCollection getDefendingBattles() {
|
||||
return CardLists.filter(Iterables.filter(attackableEntries, Card.class), CardPredicates.isType("Battle"));
|
||||
}
|
||||
|
||||
public final Map<Card, GameEntity> getAttackersAndDefenders() {
|
||||
@@ -619,17 +625,17 @@ public class Combat {
|
||||
}
|
||||
}
|
||||
|
||||
for (Card pw : getDefendingPlaneswalkers()) {
|
||||
if (pw.equals(c)) {
|
||||
for (Card battleOrPW : Iterables.filter(attackableEntries, Card.class)) {
|
||||
if (battleOrPW.equals(c)) {
|
||||
Multimap<GameEntity, AttackingBand> attackerBuffer = ArrayListMultimap.create();
|
||||
Collection<AttackingBand> bands = attackedByBands.get(c);
|
||||
for (AttackingBand abPW : bands) {
|
||||
unregisterDefender(c, abPW);
|
||||
for (AttackingBand abDef : bands) {
|
||||
unregisterDefender(c, abDef);
|
||||
// Rule 506.4c workaround to keep creatures in combat
|
||||
Card fake = new Card(-1, c.getGame());
|
||||
fake.setName("<Nothing>");
|
||||
fake.setController(c.getController(), 0);
|
||||
attackerBuffer.put(fake, abPW);
|
||||
attackerBuffer.put(fake, abDef);
|
||||
}
|
||||
bands.clear();
|
||||
attackedByBands.putAll(attackerBuffer);
|
||||
|
||||
@@ -5,7 +5,7 @@ A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one man
|
||||
A:AB$ PutCounter | Cost$ T | CounterType$ CHARGE | CounterNum$ 1 | SpellDescription$ Put a charge counter on CARDNAME.
|
||||
T:Mode$ Phase | PreCombatMain$ True | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigRemove | TriggerDescription$ At the beginning of your precombat main phase, remove all charge counters from CARDNAME. Add one mana of any color for each charge counter removed this way.
|
||||
SVar:TrigRemove:DB$ RemoveCounter | CounterType$ CHARGE | CounterNum$ All | RememberRemoved$ True | SubAbility$ TrigGetMana
|
||||
SVar:TrigGetMana:DB$ Mana | Produced$ Combo Any | Amount$ NumRemoved | AILogic$ MostProminentInComputerHand | SubAbility$ DBCleanup
|
||||
SVar:TrigGetMana:DB$ Mana | Produced$ Combo Any | Amount$ NumRemoved | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:NumRemoved:Count$RememberedSize
|
||||
Oracle:{T}: Add one mana of any color.\n{T}: Put a charge counter on Coalition Relic.\nAt the beginning of your precombat main phase, remove all charge counters from Coalition Relic. Add one mana of any color for each charge counter removed this way.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:BG
|
||||
Types:Creature Elf Shaman
|
||||
PT:1/2
|
||||
A:AB$ ChangeZone | Cost$ T | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Land | TgtPrompt$ Select target land card in a graveyard | SubAbility$ DBMana | SpellDescription$ Exile target land card from a graveyard. Add one mana of any color.
|
||||
SVar:DBMana:DB$ Mana | Produced$ Any | Amount$ 1 | AILogic$ MostProminentInComputerHand
|
||||
SVar:DBMana:DB$ Mana | Produced$ Any | Amount$ 1
|
||||
A:AB$ ChangeZone | Cost$ B T | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Instant,Sorcery | TgtPrompt$ Select target instant or sorcery card in a graveyard | SubAbility$ DBLoseLife | AITgtOwnCards$ True | SpellDescription$ Exile target instant or sorcery card from a graveyard. Each opponent loses 2 life.
|
||||
SVar:DBLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 2
|
||||
A:AB$ ChangeZone | Cost$ G T | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature | TgtPrompt$ Select target creature card in a graveyard | SubAbility$ DBGainLife | AITgtOwnCards$ True | SpellDescription$ Exile target creature card from a graveyard. You gain 2 life.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:4 U/B U/B
|
||||
Types:Legendary Creature Demon Kraken
|
||||
PT:6/6
|
||||
K:Companion:Card.cmcM20:Your starting deck contains only cards with even mana value. (If this card is your chosen companion, you may cast it once from outside the game.)
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When CARDNAME enters the battlefield, each player mills four cards. Put a creature card with an even mana value from those cards onto the battlefield under your control.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When NICKNAME enters the battlefield, each player mills four cards. Put a creature card with an even mana value from those cards onto the battlefield under your control.
|
||||
SVar:TrigMill:DB$ Mill | NumCards$ 4 | Defined$ Player | RememberMilled$ True | SubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard,Exile | Destination$ Battlefield | GainControl$ True | Mandatory$ True | Hidden$ True | ChangeNum$ 1 | ChangeType$ Card.Creature+IsRemembered+cmcM20 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Manamorphose
|
||||
ManaCost:1 RG
|
||||
Types:Instant
|
||||
A:SP$ Mana | Cost$ 1 RG | Produced$ Combo Any | Amount$ 2 | AILogic$ MostProminentInComputerHand | SubAbility$ DBDraw | SpellDescription$ Add two mana in any combination of colors. Draw a card.
|
||||
A:SP$ Mana | Cost$ 1 RG | Produced$ Combo Any | Amount$ 2 | SubAbility$ DBDraw | SpellDescription$ Add two mana in any combination of colors. Draw a card.
|
||||
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1
|
||||
AI:RemoveDeck:All
|
||||
Oracle:Add two mana in any combination of colors.\nDraw a card.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Instant
|
||||
A:SP$ Counter | Cost$ G G U U | TargetType$ Spell | RememberCounteredCMC$ True | ValidTgts$ Card | SubAbility$ DBDelTrig | SpellDescription$ Counter target spell. At the beginning of your next precombat main phase, add X mana in any combination of colors, where X is that spell's mana value.
|
||||
SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | PreCombatMain$ True | ValidPlayer$ You | Execute$ AddMana | TriggerDescription$ At the beginning of your next precombat main phase, add X mana in any combination of colors, where X is that spell's mana value. | RememberNumber$ True | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:AddMana:DB$ Mana | Produced$ Combo Any | Amount$ X | AILogic$ MostProminentInComputerHand
|
||||
SVar:AddMana:DB$ Mana | Produced$ Combo Any | Amount$ X
|
||||
SVar:X:Count$TriggerRememberAmount
|
||||
Oracle:Counter target spell. At the beginning of your next precombat main phase, add X mana in any combination of colors, where X is that spell's mana value.
|
||||
|
||||
@@ -6,5 +6,5 @@ K:Trample
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMonarch | TriggerDescription$ When CARDNAME enters the battlefield, you become the monarch.
|
||||
SVar:TrigMonarch:DB$ BecomeMonarch | Defined$ You
|
||||
T:Mode$ TapsForMana | ValidCard$ Land | Activator$ You | CheckDefinedPlayer$ You.isMonarch | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever you tap a land for mana while you're the monarch, add an additional one mana of any color.
|
||||
SVar:TrigMana:DB$ Mana | Produced$ Combo Any | Amount$ 1 | AILogic$ MostProminentInComputerHand
|
||||
SVar:TrigMana:DB$ Mana | Produced$ Combo Any | Amount$ 1
|
||||
Oracle:Trample\nWhen Regal Behemoth enters the battlefield, you become the monarch.\nWhenever you tap a land for mana while you're the monarch, add an additional one mana of any color.
|
||||
|
||||
@@ -3,9 +3,7 @@ ManaCost:B R G
|
||||
Types:Instant
|
||||
A:SP$ Charm | Choices$ DBSac,DBExilePlay,DBExileGrave
|
||||
SVar:DBSac:DB$ Sacrifice | ValidTgts$ Opponent | TgtPrompt$ Choose target opponent | SacValid$ Creature.cmcEQX,Planeswalker.cmcEQX | SacMessage$ creature or planeswalker they control with the highest mana value among creatures and planeswalkers they control | SpellDescription$ Target opponent sacrifices a creature or planeswalker they control with the highest mana value among creatures and planeswalkers they control.
|
||||
SVar:X:SVar$Y/LimitMin.Z
|
||||
SVar:Y:Count$Valid Creature.TargetedPlayerCtrl$GreatestCMC
|
||||
SVar:Z:Count$Valid Planeswalker.TargetedPlayerCtrl$GreatestCMC
|
||||
SVar:X:Count$Valid Creature.TargetedPlayerCtrl,Planeswalker.TargetedPlayerCtrl$GreatestCMC
|
||||
SVar:DBExilePlay:DB$ Dig | Defined$ You | DigNum$ 3 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top three cards of your library. Until your next end step, you may play those cards.
|
||||
SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile | Duration$ UntilYourNextEndStep
|
||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until your next end step, you may play those cards.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 G U R
|
||||
Types:Legendary Planeswalker Sarkhan
|
||||
Loyalty:4
|
||||
A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Defined$ You | SubAbility$ DBMana | Planeswalker$ True | SpellDescription$ Draw a card, then add one mana of any color.
|
||||
SVar:DBMana:DB$ Mana | Produced$ Any | AILogic$ MostProminentInComputerHand
|
||||
SVar:DBMana:DB$ Mana | Produced$ Any
|
||||
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | TokenAmount$ 1 | TokenScript$ r_4_4_dragon_flying | TokenOwner$ You | Planeswalker$ True | SpellDescription$ Create a 4/4 red Dragon creature token with flying.
|
||||
A:AB$ ChangeZone | Cost$ SubCounter<8/LOYALTY> | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.Dragon | ChangeNum$ XFetch | Planeswalker$ True | Ultimate$ True | StackDescription$ SpellDescription | SpellDescription$ Search your library for any number of Dragon creature cards, put them onto the battlefield, then shuffle.
|
||||
SVar:XFetch:Count$TypeInYourLibrary.Dragon
|
||||
|
||||
@@ -2,6 +2,6 @@ Name:Smokebraider
|
||||
ManaCost:1 R
|
||||
Types:Creature Elemental Shaman
|
||||
PT:1/1
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo Any | Amount$ 2 | RestrictValid$ Spell.Elemental,Activated.Elemental+inZoneBattlefield | AILogic$ MostProminentInComputerHand | SpellDescription$ Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elementals.
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo Any | Amount$ 2 | RestrictValid$ Spell.Elemental,Activated.Elemental+inZoneBattlefield | SpellDescription$ Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elementals.
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:{T}: Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elementals.
|
||||
|
||||
@@ -5,7 +5,5 @@ A:SP$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBChoose |
|
||||
SVar:DBChoose:DB$ ChooseCard | Defined$ Player.IsRemembered | Choices$ Creature.RememberedPlayerCtrl+cmcEQX,Planeswalker.RememberedPlayerCtrl+cmcEQX | ChoiceTitle$ Choose a creature or planeswalker with the highest mana value to sacrifice | Mandatory$ True | RememberChosen$ True
|
||||
SVar:DBSac:DB$ SacrificeAll | ValidCards$ Card.IsRemembered | SubAbility$ DBCleanup | StackDescription$ sacrifices a creature or planeswalker with the highest mana value among creatures and planeswalkers they control.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:SVar$Y/LimitMin.Z
|
||||
SVar:Y:Count$Valid Creature.RememberedPlayerCtrl$GreatestCMC
|
||||
SVar:Z:Count$Valid Planeswalker.RememberedPlayerCtrl$GreatestCMC
|
||||
SVar:X:Count$Valid Creature.RememberedPlayerCtrl,Planeswalker.RememberedPlayerCtrl$GreatestCMC
|
||||
Oracle:Each opponent sacrifices a creature or planeswalker with the highest mana value among creatures and planeswalkers they control.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Terrarion
|
||||
ManaCost:1
|
||||
Types:Artifact
|
||||
A:AB$ Mana | Cost$ 2 T Sac<1/CARDNAME> | Produced$ Combo Any | Amount$ 2 | AILogic$ MostProminentInComputerHand | SpellDescription$ Add two mana in any combination of colors.
|
||||
A:AB$ Mana | Cost$ 2 T Sac<1/CARDNAME> | Produced$ Combo Any | Amount$ 2 | SpellDescription$ Add two mana in any combination of colors.
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME is put into a graveyard from the battlefield, draw a card.
|
||||
SVar:TrigDraw:DB$ Draw | Defined$ TriggeredCardController | NumCards$ 1
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
|
||||
@@ -23,7 +23,7 @@ SVar:Exile11:DB$ ChangeZone | ValidTgts$ Player | TgtPrompt$ Select target playe
|
||||
SVar:Dig12:DB$ Dig | DigNum$ 1 | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone$ Battlefield | DestinationZone2$ Hand | SpellDescription$ Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand.
|
||||
SVar:Animate13:DB$ Animate | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control | Power$ 4 | Toughness$ 4 | Types$ Creature,Elemental | Duration$ Permanent | Keywords$ Trample | SpellDescription$ Target land you control becomes a 4/4 Elemental creature with trample. It's still a land.
|
||||
SVar:Draw14:DB$ Draw | Defined$ You | SubAbility$ DBMana14 | SpellDescription$ Draw a card, then add one mana of any color.
|
||||
SVar:DBMana14:DB$ Mana | Produced$ Any | AILogic$ MostProminentInComputerHand
|
||||
SVar:DBMana14:DB$ Mana | Produced$ Any
|
||||
SVar:Animate15:DB$ Animate | Power$ 4 | Toughness$ 4 | Types$ Creature,Legendary,Dragon | Colors$ Red | OverwriteColors$ True | RemoveCardTypes$ True | Keywords$ Flying & Indestructible & Haste | SpellDescription$ Until end of turn, NICKNAME becomes a legendary 4/4 red Dragon creature with flying, indestructible, and haste. (He doesn't lose loyalty while he's not a planeswalker.)
|
||||
SVar:PumpAll16:DB$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | KW$ Lifelink | Duration$ UntilYourNextTurn | SpellDescription$ Until your next turn, creatures you control get +1/+0 and gain lifelink.
|
||||
SVar:Dig17:DB$ Dig | DigNum$ 5 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Artifact | SpellDescription$ Look at the top five cards of your library. You may reveal an artifact card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
|
||||
|
||||
@@ -4,11 +4,11 @@ Types:Legendary Creature Phyrexian Elemental
|
||||
PT:4/4
|
||||
R:Event$ LoseMana | ValidPlayer$ You | ReplacementResult$ Replaced | ReplaceWith$ ConvertMana | ActiveZones$ Battlefield | Description$ If you would lose unspent mana, that mana becomes black instead.
|
||||
SVar:ConvertMana:DB$ ReplaceMana | ReplaceType$ Black
|
||||
T:Mode$ Phase | ValidPlayer$ You | Phase$ Main1 | TriggerZones$ Battlefield | Execute$ TrigPeek | TriggerDescription$ At the beginning of your precombat main phase, look at the top card of your library. You may reveal that card if it has three or more colored mana symbols in its mana cost. If you do, add three mana in any combination of colors and put it into your hand. If you don't reveal it, put it into your hand.
|
||||
T:Mode$ Phase | ValidPlayer$ You | Phase$ Main1 | TriggerZones$ Battlefield | Execute$ TrigPeek | TriggerDescription$ At the beginning of your precombat main phase, look at the top card of your library. You may reveal that card if it has three or more colored mana symbols in its mana cost. If you do, add three mana in any combination of its colors and put it into your hand. If you don't reveal it, put it into your hand.
|
||||
SVar:TrigPeek:DB$ PeekAndReveal | Defined$ You | NoReveal$ True | RememberPeeked$ True | SubAbility$ DBReveal
|
||||
SVar:DBReveal:DB$ PeekAndReveal | Defined$ You | NoPeek$ True | RevealOptional$ True | ImprintRevealed$ True | ConditionCheckSVar$ ColorAmount | ConditionSVarCompare$ GE3 | SubAbility$ DBMana
|
||||
SVar:DBMana:DB$ Mana | Produced$ Combo Any | Amount$ 3 | ConditionDefined$ Imprinted | ConditionPresent$ Card | SubAbility$ DBMove
|
||||
SVar:DBMana:DB$ ManaReflected | Produced$ Combo | ReflectProperty$ Is | ColorOrType$ Color | Amount$ 3 | Valid$ Defined.Imprinted | ConditionDefined$ Imprinted | ConditionPresent$ Card | SubAbility$ DBMove
|
||||
SVar:DBMove:DB$ ChangeZone | Origin$ Library | Destination$ Hand | Defined$ Remembered | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
|
||||
SVar:ColorAmount:Remembered$ChromaSource
|
||||
Oracle:If you would lose unspent mana, that mana becomes black instead.\nAt the beginning of your precombat main phase, look at the top card of your library. You may reveal that card if it has three or more colored mana symbols in its mana cost. If you do, add three mana in any combination of colors and put it into your hand. If you don't reveal it, put it into your hand.
|
||||
Oracle:If you would lose unspent mana, that mana becomes black instead.\nAt the beginning of your precombat main phase, look at the top card of your library. You may reveal that card if it has three or more colored mana symbols in its mana cost. If you do, add three mana in any combination of its colors and put it into your hand. If you don't reveal it, put it into your hand.
|
||||
|
||||
@@ -6,7 +6,7 @@ S:Mode$ Continuous | Affected$ Land.YouCtrl | AddAbility$ AnyMana | Description$
|
||||
SVar:AnyMana:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color.
|
||||
A:AB$ Animate | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Land.YouCtrl | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target land you control | Power$ 3 | Toughness$ 3 | Types$ Creature,Elemental | Keywords$ Vigilance & Hexproof & Haste | Duration$ UntilYourNextTurn | SpellDescription$ Up to one target land you control becomes a 3/3 Elemental creature with vigilance, hexproof, and haste until your next turn. It's still a land.
|
||||
A:AB$ Mill | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | NumCards$ 3 | RememberMilled$ True | SubAbility$ DBChangeZone | SpellDescription$ Mill three cards. You may put a permanent card from among the milled cards into your hand.
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Hidden$ True | ChangeNum$ 1 | ChangeType$ Card.Permanent+IsRemembered | SubAbility$ DBCleanup
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard,Exile | Destination$ Hand | Hidden$ True | ChangeNum$ 1 | ChangeType$ Card.Permanent+IsRemembered | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
A:AB$ Effect | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem - Wrenn and Realmbreaker | Image$ emblem_wrenn_and_realmbreaker | StaticAbilities$ PermanentRecycle | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "You may play lands and cast permanent spells from your graveyard."
|
||||
SVar:PermanentRecycle:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Permanent+YouOwn | MayPlay$ True | AffectedZone$ Graveyard | Description$ You may play lands and cast permanent spells from your graveyard.
|
||||
|
||||
Reference in New Issue
Block a user