...
 
Commits (74)
......@@ -1042,9 +1042,10 @@ public class AiController {
}
public CardCollection getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa, final CardCollectionView exclude) {
boolean noFiltering = (sa != null) && "DiscardCMCX".equals(sa.getParam("AILogic")); // list AI logic for which filtering is taken care of elsewhere
CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand));
hand.removeAll(exclude);
if ((uTypes != null) && (sa != null)) {
if ((uTypes != null) && (sa != null) && !noFiltering) {
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getHostCard(), sa);
}
return getCardsToDiscard(numDiscard, numDiscard, hand, sa);
......@@ -1064,6 +1065,14 @@ public class AiController {
min = 1;
} else if ("VolrathsShapeshifter".equals(sa.getParam("AILogic"))) {
return SpecialCardAi.VolrathsShapeshifter.targetBestCreature(player, sa);
} else if ("DiscardCMCX".equals(sa.getParam("AILogic"))) {
final int CMC = Integer.parseInt(sourceCard.getSVar("PayX"));
CardCollection discards = CardLists.filter(player.getCardsIn(ZoneType.Hand), CardPredicates.hasCMC(CMC));
if (discards.isEmpty()) {
return null;
} else {
return new CardCollection(ComputerUtilCard.getWorstAI(discards));
}
}
if (sa.hasParam("AnyNumber")) {
......
......@@ -1930,12 +1930,19 @@ public class ComputerUtil {
}
public static int scoreHand(CardCollectionView handList, Player ai) {
public static int scoreHand(CardCollectionView handList, Player ai, int cardsToReturn) {
// TODO Improve hand scoring in relation to cards to return.
// If final hand size is 5, score a hand based on what that 5 would be.
// Or if this is really really fast, determine what the 5 would be based on scoring
// All of the possibilities
final AiController aic = ((PlayerControllerAi)ai.getController()).getAi();
int currentHandSize = handList.size();
int finalHandSize = currentHandSize - cardsToReturn;
// don't mulligan when already too low
if (handList.size() < aic.getIntProperty(AiProps.MULLIGAN_THRESHOLD)) {
return handList.size();
if (finalHandSize < aic.getIntProperty(AiProps.MULLIGAN_THRESHOLD)) {
return finalHandSize;
}
CardCollectionView library = ai.getZone(ZoneType.Library).getCards();
......@@ -1943,7 +1950,7 @@ public class ComputerUtil {
// no land deck, can't do anything better
if (landsInDeck == 0) {
return handList.size();
return finalHandSize;
}
final CardCollectionView lands = CardLists.filter(handList, new Predicate<Card>() {
......@@ -2011,9 +2018,9 @@ public class ComputerUtil {
}
// Computer mulligans if there are no cards with converted mana cost of 0 in its hand
public static boolean wantMulligan(Player ai) {
public static boolean wantMulligan(Player ai, int cardsToReturn) {
final CardCollectionView handList = ai.getCardsIn(ZoneType.Hand);
return scoreHand(handList, ai) <= 0;
return scoreHand(handList, ai, cardsToReturn) <= 0;
}
public static CardCollection getPartialParisCandidates(Player ai) {
......
......@@ -110,6 +110,15 @@ public class ComputerUtilCost {
&& !source.hasKeyword(Keyword.UNDYING)) {
return false;
}
} else if (part instanceof CostRemoveAnyCounter) {
if (sa != null) {
final CostRemoveAnyCounter remCounter = (CostRemoveAnyCounter) part;
PaymentDecision decision = new AiCostDecision(sa.getActivatingPlayer(), sa).visit(remCounter);
return decision != null;
}
return false;
}
}
return true;
......
......@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.*;
import forge.ai.ability.AnimateAi;
import forge.card.CardStateName;
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaAtom;
......@@ -1121,11 +1122,11 @@ public class ComputerUtilMana {
// For Count$xPaid set PayX in the AFs then use that here
// Else calculate it as appropriate.
final String xSvar = card.getSVar("X").startsWith("Count$xPaid") ? "PayX" : "X";
if (!sa.getSVar(xSvar).isEmpty() || card.hasSVar(xSvar)) {
if (xSvar.equals("PayX") && card.hasSVar(xSvar)) {
if (!sa.getSVar(xSvar).isEmpty() || card.hasSVar(xSvar) || card.getState(CardStateName.Original).hasSVar(xSvar)) {
if (xSvar.equals("PayX") && (card.hasSVar(xSvar) || card.getState(CardStateName.Original).hasSVar(xSvar))) {
// X SVar may end up being an empty string when copying a spell with no cost (e.g. Jhoira Avatar)
String xValue = card.getSVar(xSvar);
manaToAdd = xValue.isEmpty() ? 0 : Integer.parseInt(card.getSVar(xSvar)) * cost.getXcounter(); // X
String xValue = card.hasSVar(xSvar) ? card.getSVar(xSvar) : card.getState(CardStateName.Original).getSVar(xSvar);
manaToAdd = xValue.isEmpty() ? 0 : Integer.parseInt(xValue) * cost.getXcounter(); // X
} else {
manaToAdd = AbilityUtils.calculateAmount(card, xSvar, sa) * cost.getXcounter();
}
......
......@@ -536,15 +536,29 @@ public class PlayerControllerAi extends PlayerController {
return brains.aiShouldRun(replacementEffect, effectSA);
}
@Override
public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) {
return !ComputerUtil.wantMulligan(player, cardsToReturn);
}
@Override
public CardCollectionView getCardsToMulligan(Player firstPlayer) {
if (!ComputerUtil.wantMulligan(player)) {
if (!ComputerUtil.wantMulligan(player, 0)) {
return null;
}
return player.getCardsIn(ZoneType.Hand);
}
@Override
public CardCollectionView londonMulliganReturnCards(final Player mulliganingPlayer, int cardsToReturn) {
// TODO This is awful. Don't do this.
// Maybe score a bunch of hands based on projected hand size and return the "duds"
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
return CardCollection.getView(hand.subList(0, cardsToReturn));
}
@Override
public void declareAttackers(Player attacker, Combat combat) {
brains.declareAttackers(attacker, combat);
......
......@@ -1456,6 +1456,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
} else if ("WorstCard".equals(logic)) {
return ComputerUtilCard.getWorstAI(fetchList);
} else if ("BestCard".equals(logic)) {
return ComputerUtilCard.getBestAI(fetchList); // generally also means the most expensive one or close to it
} else if ("Mairsil".equals(logic)) {
return SpecialCardAi.MairsilThePretender.considerCardFromList(fetchList);
} else if ("SurvivalOfTheFittest".equals(logic)) {
......
......@@ -75,7 +75,7 @@ public class DamageDealAi extends DamageAiBase {
// Set PayX here to maximum value.
dmg = ComputerUtilMana.determineLeftoverMana(sa, ai);
sa.setSVar("PayX", Integer.toString(dmg));
source.setSVar("PayX", Integer.toString(dmg));
} else if (sa.getSVar(damage).equals("Count$CardsInYourHand") && source.getZone().is(ZoneType.Hand)) {
dmg--; // the card will be spent casting the spell, so actual damage is 1 less
}
......@@ -115,7 +115,7 @@ public class DamageDealAi extends DamageAiBase {
}
// Set PayX here to maximum value. It will be adjusted later depending on the target.
sa.setSVar("PayX", Integer.toString(dmg));
source.setSVar("PayX", Integer.toString(dmg));
} else if (sa.getSVar(damage).contains("InYourHand") && source.getZone().is(ZoneType.Hand)) {
dmg = CardFactoryUtil.xCount(source, sa.getSVar(damage)) - 1; // the card will be spent casting the spell, so actual damage is 1 less
} else if (sa.getSVar(damage).equals("TargetedPlayer$CardsInHand")) {
......@@ -272,7 +272,7 @@ public class DamageDealAi extends DamageAiBase {
sourceName.equals("Crater's Claws")){
// If I can kill my target by paying less mana, do it
if (sa.usesTargeting() && !sa.getTargets().isTargetingAnyPlayer() && !sa.hasParam("DividedAsYouChoose")) {
int actualPay = 0;
int actualPay = dmg;
final boolean noPrevention = sa.hasParam("NoPrevention");
for (final Card c : sa.getTargets().getTargetCards()) {
final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
......@@ -283,7 +283,7 @@ public class DamageDealAi extends DamageAiBase {
if (sourceName.equals("Crater's Claws") && ai.hasFerocious()) {
actualPay = actualPay > 2 ? actualPay - 2 : 0;
}
sa.setSVar("PayX", Integer.toString(actualPay));
source.setSVar("PayX", Integer.toString(actualPay));
}
}
......@@ -299,6 +299,11 @@ public class DamageDealAi extends DamageAiBase {
}
}
if ("DiscardCMCX".equals(sa.getParam("AILogic"))) {
final int CMC = Integer.parseInt(source.getSVar("PayX"));
return !CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.hasCMC(CMC)).isEmpty();
}
return true;
}
......@@ -941,7 +946,7 @@ public class DamageDealAi extends DamageAiBase {
if (damage.equals("X") && sa.getSVar(damage).equals("Count$xPaid")) {
// Set PayX here to maximum value.
dmg = ComputerUtilMana.determineLeftoverMana(sa, ai);
sa.setSVar("PayX", Integer.toString(dmg));
source.setSVar("PayX", Integer.toString(dmg));
}
final TargetRestrictions tgt = sa.getTargetRestrictions();
......@@ -971,7 +976,7 @@ public class DamageDealAi extends DamageAiBase {
}
}
sa.setSVar("PayX", Integer.toString(actualPay));
source.setSVar("PayX", Integer.toString(actualPay));
}
}
......@@ -1031,7 +1036,7 @@ public class DamageDealAi extends DamageAiBase {
saTgt.resetTargets();
saTgt.getTargets().add(tgtCreature != null && dmg < opponent.getLife() ? tgtCreature : opponent);
sa.setSVar("PayX", Integer.toString(dmg));
source.setSVar("PayX", Integer.toString(dmg));
return true;
}
......
......@@ -107,7 +107,7 @@ public class DrawAi extends SpellAbilityAi {
}
}
if (!ComputerUtilCost.checkRemoveCounterCost(cost, source)) {
if (!ComputerUtilCost.checkRemoveCounterCost(cost, source, sa)) {
return false;
}
......
......@@ -29,6 +29,7 @@ import forge.game.ability.effects.AttachEffect;
import forge.game.card.*;
import forge.game.event.*;
import forge.game.keyword.KeywordInterface;
import forge.game.mulligan.MulliganService;
import forge.game.player.GameLossReason;
import forge.game.player.Player;
import forge.game.replacement.ReplacementEffect;
......@@ -48,8 +49,6 @@ import forge.item.PaperCard;
import forge.util.*;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import forge.util.maps.HashMapOfLists;
import forge.util.maps.MapOfLists;
import org.apache.commons.lang3.tuple.ImmutablePair;
import java.util.*;
......@@ -185,7 +184,7 @@ public class GameAction {
// all sort of funky shenanigans may happen later (e.g. their ETB replacement effects are set
// up on the wrong card state etc.).
if (wasFacedown && (fromBattlefield || (toHand && zoneFrom.is(ZoneType.Exile)))) {
c.turnFaceUp();
c.turnFaceUp(false, false);
}
if (!c.isToken()) {
......@@ -1577,7 +1576,7 @@ public class GameAction {
// Choose starting hand for each player with multiple hands
if (game.getRules().getGameType() != GameType.Puzzle) {
performMulligans(first, game.getRules().hasAppliedVariant(GameType.Commander));
new MulliganService(first).perform();
}
if (game.isGameOver()) { break; } // conceded during "mulligan" prompt
......@@ -1667,79 +1666,6 @@ public class GameAction {
return goesFirst;
}
private void performMulligans(final Player firstPlayer, final boolean isCommander) {
List<Player> whoCanMulligan = Lists.newArrayList(game.getPlayers());
int offset = whoCanMulligan.indexOf(firstPlayer);
// Have to cycle-shift the list to get the first player on index 0
for (int i = 0; i < offset; i++) {
whoCanMulligan.add(whoCanMulligan.remove(0));
}
boolean[] hasKept = new boolean[whoCanMulligan.size()];
int[] handSize = new int[whoCanMulligan.size()];
for (int i = 0; i < whoCanMulligan.size(); i++) {
hasKept[i] = false;
handSize[i] = whoCanMulligan.get(i).getZone(ZoneType.Hand).size();
}
MapOfLists<Player, Card> exiledDuringMulligans = new HashMapOfLists<Player, Card>(CollectionSuppliers.<Card>arrayLists());
// rule 103.4b
boolean isMultiPlayer = game.getPlayers().size() > 2;
// https://magic.wizards.com/en/articles/archive/feature/checking-brawl-2018-07-09
int mulliganDelta = isMultiPlayer || game.getRules().hasAppliedVariant(GameType.Brawl) ? 0 : 1;
boolean allKept;
do {
allKept = true;
for (int i = 0; i < whoCanMulligan.size(); i++) {
if (hasKept[i]) continue;
Player p = whoCanMulligan.get(i);
CardCollectionView toMulligan = p.canMulligan() ? p.getController().getCardsToMulligan(firstPlayer) : null;
if (game.isGameOver()) { // conceded on mulligan prompt
return;
}
if (toMulligan != null && !toMulligan.isEmpty()) {
toMulligan = new CardCollection(p.getCardsIn(ZoneType.Hand));
for (final Card c : toMulligan) {
moveToLibrary(c, null, null);
}
try {
Thread.sleep(100); //delay for a tiny bit to give UI a chance catch up
} catch (InterruptedException e) {
e.printStackTrace();
}
p.shuffle(null);
p.drawCards(handSize[i] - mulliganDelta);
p.onMulliganned();
allKept = false;
} else {
game.getGameLog().add(GameLogEntryType.MULLIGAN, p.getName() + " has kept a hand of " + p.getZone(ZoneType.Hand).size() + " cards");
hasKept[i] = true;
}
}
mulliganDelta++;
} while (!allKept);
//Vancouver Mulligan as a scry with the decisions inside
List<Player> scryers = Lists.newArrayList();
for(Player p : whoCanMulligan) {
if (p.getStartingHandSize() > p.getZone(ZoneType.Hand).size()) {
scryers.add(p);
}
}
for(Player p : scryers) {
if (p.getController().confirmMulliganScry(p)) {
scry(ImmutableList.of(p), 1, null);
}
}
}
private void runPreOpeningHandActions(final Player first) {
Player takesAction = first;
do {
......
package forge.game.mulligan;
import forge.game.GameLogEntryType;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
public abstract class AbstractMulligan {
Player player;
int timesMulliganed = 0;
boolean firstMulliganFree = false;
boolean kept = false;
public AbstractMulligan(Player p, boolean firstMullFree) {
player = p;
firstMulliganFree = firstMullFree;
}
public Player getPlayer() { return player; }
public abstract boolean canMulligan();
public abstract int handSizeAfterNextMulligan();
public int tuckCardsAfterKeepHand() {
return 0;
}
public void mulligan() {
CardCollection toMulligan = new CardCollection(player.getCardsIn(ZoneType.Hand));
revealPreMulligan(toMulligan);
for (final Card c : toMulligan) {
player.getGame().getAction().moveToLibrary(c, null, null);
}
try {
Thread.sleep(100); //delay for a tiny bit to give UI a chance catch up
} catch (InterruptedException e) {
e.printStackTrace();
}
player.shuffle(null);
timesMulliganed++;
mulliganDraw();
player.onMulliganned();
}
public void keep() {
kept = true;
}
public boolean hasKept() {
return kept;
}
public void revealPreMulligan(CardCollection toMulligan) {}
public void mulliganDraw() {
player.drawCards(handSizeAfterNextMulligan());
}
public void afterMulligan() {
player.getGame().getGameLog().add(GameLogEntryType.MULLIGAN, player.getName() + " has kept a hand of " + player.getZone(ZoneType.Hand).size() + " cards");
}
}
package forge.game.mulligan;
import forge.game.player.Player;
public class LondonMulligan extends AbstractMulligan {
public LondonMulligan(Player p, boolean firstMullFree) {
super(p, firstMullFree);
}
@Override
public boolean canMulligan() {
return !kept && timesMulliganed < player.getMaxHandSize();
}
@Override
public int handSizeAfterNextMulligan() {
return player.getMaxHandSize();
}
@Override
public int tuckCardsAfterKeepHand() {
if (timesMulliganed == 0) {
return 0;
}
int extraCard = firstMulliganFree ? 1 : 0;
return timesMulliganed - extraCard;
}
@Override
public void afterMulligan() {
int tuckingCards = tuckCardsAfterKeepHand();
player.getController().londonMulliganReturnCards(player, tuckingCards);
super.afterMulligan();
}
}
package forge.game.mulligan;
import java.util.List;
import com.google.common.collect.Lists;
import forge.game.Game;
import forge.game.GameType;
import forge.game.player.Player;
public class MulliganService {
Player firstPlayer;
Game game;
List<AbstractMulligan> mulligans = Lists.newArrayList();
public MulliganService(Player player) {
firstPlayer = player;
game = firstPlayer.getGame();
}
public void perform() {
initializeMulligans();
runPlayerMulligans();
}
private void initializeMulligans() {
List<Player> whoCanMulligan = Lists.newArrayList(game.getPlayers());
int offset = whoCanMulligan.indexOf(firstPlayer);
// Have to cycle-shift the list to get the first player on index 0
for (int i = 0; i < offset; i++) {
whoCanMulligan.add(whoCanMulligan.remove(0));
}
boolean firstMullFree = game.getPlayers().size() > 2 || game.getRules().hasAppliedVariant(GameType.Brawl);
for (int i = 0; i < whoCanMulligan.size(); i++) {
// hook in the UI for different mulligans here
mulligans.add(new VancouverMulligan(whoCanMulligan.get(i), firstMullFree));
}
}
private void runPlayerMulligans() {
boolean allKept;
do {
allKept = true;
for(AbstractMulligan mulligan : mulligans) {
if (mulligan.hasKept()) {
continue;
}
Player p = mulligan.getPlayer();
boolean keep = mulligan.canMulligan() ? p.getController().mulliganKeepHand(firstPlayer, mulligan.tuckCardsAfterKeepHand()) : true;
if (game.isGameOver()) { // conceded on mulligan prompt
return;
}
if (keep) {
mulligan.keep();
continue;
}
allKept = false;
mulligan.mulligan();
}
} while (!allKept);
for(AbstractMulligan mulligan : mulligans) {
mulligan.afterMulligan();
}
}
}
\ No newline at end of file
package forge.game.mulligan;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
public class OriginalMulligan extends AbstractMulligan {
public OriginalMulligan(Player p, boolean firstMullFree) {
super(p, firstMullFree);
}
public boolean canMulligan() {
if (timesMulliganed > 0) {
return false;
}
int totalCards = 0;
int lands = 0;
for(Card c : player.getCardsIn(ZoneType.Hand)) {
if (c.isLand()) {
lands++;
}
totalCards++;
}
return lands == 0 || lands == totalCards;
}
@Override
public void revealPreMulligan(CardCollection toMulligan) {
for(Card card : toMulligan) {
// TODO Reveal the cards.
}
}
public void mulliganDraw() {
player.drawCards(handSizeAfterNextMulligan());
}
public int handSizeAfterNextMulligan() {
return player.getMaxHandSize();
}
}
package forge.game.mulligan;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
public class ParisMulligan extends AbstractMulligan {
public ParisMulligan(Player p, boolean firstMullFree) {
super(p, firstMullFree);
}
public boolean canMulligan() {
return !kept && !player.getZone(ZoneType.Hand).isEmpty();
}
public int handSizeAfterNextMulligan() {
int extraCard = firstMulliganFree ? 1 : 0;
return player.getMaxHandSize() - timesMulliganed + extraCard;
}
}
package forge.game.mulligan;
import com.google.common.collect.ImmutableList;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
public class VancouverMulligan extends ParisMulligan {
public VancouverMulligan(Player p, boolean firstMullFree) {
super(p, firstMullFree);
}
public void afterMulligan() {
super.afterMulligan();
if (player.getStartingHandSize() > player.getZone(ZoneType.Hand).size()) {
player.getGame().getAction().scry(ImmutableList.of(player), 1, null);
}
}
}
......@@ -169,7 +169,10 @@ public abstract class PlayerController {
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes);
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
public abstract CardCollectionView getCardsToMulligan(Player firstPlayer);
public abstract boolean mulliganKeepHand(Player player, int cardsToReturn);
public abstract CardCollectionView londonMulliganReturnCards(Player mulliganingPlayer, int cardsToReturn);
public abstract void declareAttackers(Player attacker, Combat combat);
public abstract void declareBlockers(Player defender, Combat combat);
......
......@@ -303,6 +303,17 @@ public class PlayerControllerForTests extends PlayerController {
return true;
}
@Override
public CardCollectionView londonMulliganReturnCards(final Player mulliganingPlayer, int cardsToReturn) {
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
return hand;
}
@Override
public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) {
return true;
}
@Override
public CardCollectionView getCardsToMulligan(Player firstPlayer) {
return null;
......
Agetian
apantel
Austinio7116
Churrufli
DrDev
......
......@@ -3,7 +3,7 @@ ManaCost:1 R
Types:Creature Human Shaman
PT:2/1
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Landfall — Whenever a land enters the battlefield under your control, you may pay {2}{R}. If you do, create a 3/1 red Elemental creature token with trample and haste. Exile that token at the beginning of the next end step.
SVar:TrigToken:AB$Token | Cost$ 2 R | TokenScript$ r_3_1_elemental_trample_haste | LegacyImage$ r 3 1 elemental trample haste bfz AtEOT$ Exile
SVar:TrigToken:AB$Token | Cost$ 2 R | TokenScript$ r_3_1_elemental_trample_haste | LegacyImage$ r 3 1 elemental trample haste bfz | AtEOT$ Exile
DeckHas:Ability$Token
SVar:Picture:http://www.wizards.com/global/images/magic/general/akoum_stonewaker.jpg
Oracle:Landfall — Whenever a land enters the battlefield under your control, you may pay {2}{R}. If you do, create a 3/1 red Elemental creature token with trample and haste. Exile that token at the beginning of the next end step.
Name:Condemn
ManaCost:W
Types:Instant
A:SP$ ChangeZone | Cost$ W | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | Origin$ Battlefield | Destination$ Library | LibraryPosition$ -1 | SubAbility$ DBGainLife | SpellDescription$ Put target attacking creature on the bottom of its owner's library. Its controller gains life equal to its toughness.
SVar:DBGainLife:DB$GainLife | Defined$ TargetedController | LifeAmount$ X | References$ X
SVar:X:Targeted$CardToughness
A:SP$ ChangeZone | Cost$ W | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | Origin$ Battlefield | Destination$ Library | LibraryPosition$ -1 | SubAbility$ DBGainLife | RememberLKI$ True | SpellDescription$ Put target attacking creature on the bottom of its owner's library. Its controller gains life equal to its toughness.
SVar:DBGainLife:DB$GainLife | Defined$ RememberedController | LifeAmount$ X | References$ X
SVar:X:RememberedLKI$CardToughness
SVar:Picture:http://www.wizards.com/global/images/magic/general/condemn.jpg
Oracle:Put target attacking creature on the bottom of its owner's library. Its controller gains life equal to its toughness.
......@@ -11,7 +11,7 @@ ALTERNATE
Name:Seek
ManaCost:W B
Types:Instant
A:SP$ ChangeZone | Cost$ W B | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Origin$ Library | DefinedPlayer$ Targeted | Chooser$ You | Destination$ Exile | Changetype$ Card | ChangeNum$ 1 | RememberChanged$ True | SubAbility$ DBGainLife | StackDescription$ SpellDescription | SpellDescription$ Search target opponent's library for a card and exile it. You gain life equal to its converted mana cost. Then that player shuffles their library.
A:SP$ ChangeZone | Cost$ W B | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Origin$ Library | DefinedPlayer$ Targeted | Chooser$ You | Destination$ Exile | Changetype$ Card | ChangeNum$ 1 | RememberChanged$ True | IsCurse$ True | AILogic$ BestCard | SubAbility$ DBGainLife | StackDescription$ SpellDescription | SpellDescription$ Search target opponent's library for a card and exile it. You gain life equal to its converted mana cost. Then that player shuffles their library.
SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | References$ X | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$CardManaCost
......
Name:Knollspine Invocation
ManaCost:1 R R
Types:Enchantment
A:AB$ DealDamage | Announce$ X | Cost$ X Discard<1/Card.cmcEQX/card with converted mana cost X> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X | SpellDescription$ CARDNAME deals X damage to any target.
A:AB$ DealDamage | Announce$ X | Cost$ X Discard<1/Card.cmcEQX/card with converted mana cost X> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X | AILogic$ DiscardCMCX | SpellDescription$ CARDNAME deals X damage to any target.
SVar:X:Count$xPaid
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/knollspine_invocation.jpg
Oracle:{X}, Discard a card with converted mana cost X: Knollspine Invocation deals X damage to any target.
......@@ -2,9 +2,10 @@ Name:Orim's Thunder
ManaCost:2 W
Types:Instant
K:Kicker:R
A:SP$ Destroy | Cost$ 2 W | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | RememberTargets$ True | ForgetOtherTargets$ True | SubAbility$ DBDamage | SpellDescription$ Destroy target artifact or enchantment.
SVar:DBDamage:DB$DealDamage | Condition$ Kicked | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | References$ X | SpellDescription$ If CARDNAME was kicked, it deals damage equal to that permanent's converted mana cost to target creature.
SVar:X:Remembered$CardManaCost
A:SP$ Destroy | Cost$ 2 W | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SubAbility$ DBDamage | SpellDescription$ Destroy target artifact or enchantment.
SVar:DBDamage:DB$DealDamage | Condition$ Kicked | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | References$ X | TargetMin$ Y | TargetMax$ Y | SpellDescription$ If CARDNAME was kicked, it deals damage equal to that permanent's converted mana cost to target creature.
SVar:X:Targeted$CardManaCost
SVar:Y:Count$Kicked.1.0
DeckHints:Color$Red
SVar:Picture:http://www.wizards.com/global/images/magic/general/orims_thunder.jpg
Oracle:Kicker {R} (You may pay an additional {R} as you cast this spell.)\nDestroy target artifact or enchantment. If Orim's Thunder was kicked, it deals damage equal to that permanent's converted mana cost to target creature.
Name:Archmage's Charm
Types:Instant
ManaCost:U U U
A:SP$ Charm | Cost$ U U U | Choices$ DBCounter,DBDraw,DBControl
SVar:DBCounter:DB$ Counter | TargetType$ Spell | ValidTgts$ Card | SpellDescription$ Counter target spell.
SVar:DBDraw:DB$ Draw | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player draws two cards.
SVar:DBControl:DB$ GainControl | ValidTgts$ Permanent.nonLand+cmcLE1 | TgtPrompt$ Select target nonland permanent with converted mana cost 1 or less. | SpellDescription$ Gain control of target nonland permanent with converted mana cost 1 or less.
Oracle:Choose one —\n• Counter target spell.\n• Target player draws two cards.\n• Gain control of target nonland permanent with converted mana cost 1 or less.
\ No newline at end of file
Name:Arcum's Astrolabe
ManaCost:S
Types:Snow Artifact
Colors:green
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, draw a card.
SVar:TrigDraw:DB$Draw | Defined$ You | NumCards$ 1
A:AB$ Mana | Cost$ 1 T | Produced$ Any | SpellDescription$ Add one mana of any color.
AI:RemoveDeck:All
Oracle:({S} can be paid with one mana from a snow permanent.)\nWhen Arcum's Astrolabe enters the battlefield, draw a card.\n{1}, {T}: Add one mana of any color.
Name:Bladeback Sliver
ManaCost:1 R
Types:Creature Sliver
PT:2/2
S:Mode$ Continuous | Affected$ Creature.Sliver+YouCtrl | AddAbility$ DBDamage | Condition$ Hellbent | Description$ Hellbent As long as you have no cards in hand, Sliver creatures you control have "{T}: This creature deals 1 damage to target player or planeswalker.
SVar:DBDamage:AB$ DealDamage | Cost$ T | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | SpellDescription$ This creature deals 1 damage to target player or planeswalker.
SVar:PlayMain1:TRUE
Oracle:Hellbent — As long as you have no cards in hand, Sliver creatures you control have "{T}: This creature deals 1 damage to target player or planeswalker."
Name:Collector Ouphe
ManaCost:1 G
Types:Creature Ouphe
PT:2/2
S:Mode$ Continuous | Affected$ Artifact | AddHiddenKeyword$ CARDNAME's activated abilities can't be activated. | Description$ Activated abilities of artifacts can't be activated.
AI:RemoveDeck:Random
Oracle:Activated abilities of artifacts can't be activated.
Name:Crashing Footfalls
ManaCost:no cost
Types:Sorcery
K:Suspend:4:G
SVar:NonStackingEffect:True
AI:RemoveDeck:Random
A:SP$ Token | Cost$ 0 | TokenAmount$ 2 | TokenScript$ g_4_4_rhino_trample | TokenOwner$ You | LegacyImage$ g 4 4 rhino trample mh1 | SpellDescription$ Create two 4/4 green Rhino creature tokens with trample.
Oracle:Suspend 4—{G} (Rather than cast this card from your hand, pay {G} and exile it with four time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost.)\nCreate two 4/4 green Rhino creature tokens with trample.
Name:Enduring Sliver
ManaCost:1 W
Types:Creature Sliver
PT:2/2
K:Outlast:2
DeckHas:Ability$Counters
S:Mode$ Continuous | Affected$ Sliver.YouCtrl+Other | AddKeyword$ Outlast:2 | Description$ Other Sliver creatures you control have outlast {2}.
SVar:PlayMain1:TRUE
Oracle:Outlast {2} ({2}, {T}: Put a +1/+1 counter on this creature. Outlast only as a sorcery.)\nOther sliver creatures you control have outlast {2}.
Name:Goatnap
ManaCost:2 R
Types:Sorcery
A:SP$ GainControl | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | Untap$ True | LoseControl$ EOT | SubAbility$ DBPump | SpellDescription$ Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a, it also gets +3/+0 until end of turn.
A:SP$ GainControl | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | Untap$ True | AddKWs$ Haste | LoseControl$ EOT | SubAbility$ DBPump | SpellDescription$ Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a, it also gets +3/+0 until end of turn.
SVar:DBPump:DB$ Pump | Defined$ Targeted | NumAtt$ 3 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | References$ X
SVar:X:Targeted$Valid Goat
Oracle:Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a goat, it also gets +3/+0 until end of turn.
Name:Goblin Champion
ManaCost:R
Types:Creature Goblin Warrior
PT:0/1
K:Haste
K:Exalted
Oracle:Haste\nExalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.)
Name:Goblin Oriflamme
ManaCost:1 R
Types:Enchantment
S:Mode$ Continuous | Affected$ Creature.attacking+YouCtrl | AddPower$ 1 | Description$ Attacking creatures you control get +1/+0.
SVar:PlayMain1:TRUE
Oracle:Attacking creatures you control get +1/+0.
Name:Hexdrinker
ManaCost:G
Types:Creature Snake
PT:2/1
K:Level up:1
SVar:maxLevel:8
S:Mode$ Continuous | Affected$ Card.Self | SetPower$ 4 | SetToughness$ 4 | AddKeyword$ Protection:Instant:Protection from instants | IsPresent$ Card.Self+counters_GE3_LEVEL+counters_LT8_LEVEL | Description$ LEVEL 3-7 4/4 CARDNAME has Protection from Instants
S:Mode$ Continuous | Affected$ Card.Self | SetPower$ 6 | SetToughness$ 6 | AddKeyword$ Protection from everything | IsPresent$ Card.Self+counters_GE8_LEVEL | Description$ LEVEL 8+ 6/6 CARDNAME has Protection from everything
Oracle:Level up {1} ({1}: Put a level counter on this. Level up only as a sorcery.)\nLEVEL 3-7\n4/4\nProtection from instants\nLEVEL 8+\n6/6\nProtection from everything
Name:Ingenious Infiltrator
ManaCost:2 U B
Types:Creature Vedalken Ninja
PT:2/3
K:Ninjutsu:U B
T:Mode$ DamageDone | ValidSource$ Ninja.YouCtrl | ValidTarget$ Player | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a Ninja you control deals combat damage to a player, draw a card.
SVar:TrigDraw:DB$ Draw | NumCards$ 1
AI:RemoveDeck:Random
DeckHints:Type$Ninja
Oracle:Ninjutsu {U}{B} ({U}{B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.)\nWhenever a Ninja you control deals combat damage to a player, draw a card.
Name:Kaya's Guile
Types:Instant
ManaCost:1 W B
K:Entwine:3
A:SP$ Charm | Cost$ 1 W B | Choices$ DBSac,DBExile,DBSpirit,DBGain | CharmNum$ 2
SVar:DBSac:DB$ Sacrifice | Defined$ Player.Opponent | SacValid$ Creature | SacMessage$ creature | SpellDescription$ Each opponent sacrifices a creature.
SVar:DBExile:DB$ ChangeZoneAll | ChangeType$ Card.OppCtrl | Origin$ Graveyard | Destination$ Exile | SpellDescription$ Exile all cards from each opponent's graveyard.
SVar:DBSpirit:DB$Token | TokenAmount$ 1 | TokenScript$ wb_1_1_spirit_flying | TokenOwner$ You | LegacyImage$ wb 1 1 spirit mh1 | SpellDescription$ Create a 1/1 white and black Spirit creature token with flying.
SVar:DBGain:DB$ GainLife | LifeAmount$ 4 | SpellDescription$ You gain 4 life.
Oracle:Choose two —\n• Each opponent sacrifices a creature.\n• Exile all cards from each opponent's graveyard.\n• Create a 1/1 white and black Spirit creature token with flying. \n• You gain 4 life.\nEntwine {3} (Choose all if you pay the entwine cost.)
Name:Nature's Chant
ManaCost:1 GW
Types:Instant
A:SP$ Destroy | Cost$ 1 GW | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SpellDescription$ Destroy target artifact or enchantment.
Oracle:Destroy target artifact or enchantment.
Name:Ore-Scale Guardian
ManaCost:5 R R
Types:Creature Dragon
PT:4/4
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | References$ X | EffectZone$ All | Description$ CARDNAME costs {1} less to cast for each land card in your graveyard.
SVar:X:Count$TypeInYourYard.Land
K:Flying
K:Haste
Oracle:This spell costs {1} less to cast for each land card in your graveyard.\nFlying, haste
Name:Pashalik Mons
Types:Legendary Creature Goblin Warrior
ManaCost:2 R
PT:2/2
T:Mode$ ChangesZone | Origins$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ DBDamage | TriggerController$ TriggeredCardController | TriggerDescription$ Whenever CARDNAME or another Goblin you control dies, CARDNAME deals 1 damage to any target.
T:Mode$ ChangesZone | Origins$ Battlefield | Destination$ Graveyard | ValidCard$ Goblin.Other+YouCtrl | Execute$ DBDamage | TriggerZones$ Battlefield | TriggerController$ TriggeredCardController | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another Goblin you control dies, CARDNAME deals 1 damage to any target.
SVar:DBDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1
A:AB$ Token | Cost$ 3 R Sac<1/Goblin> | TokenAmount$ 2 | TokenScript$ r_1_1_goblin | TokenOwner$ You | LegacyImage$ r 1 1 goblin mh1 | SpellDescription$ Create two 1/1 red Goblin creature tokens.
Oracle:Whenever Pashalik Mons or another Goblin you control dies, Pashalik Mons deals 1 damage to any target.\n{3}{R}, Sacrifice a Goblin: Create two 1/1 red Goblin creature tokens.
Name:Ruination Rioter
ManaCost:R G
Types:Creature Human Berserker
PT:1/1
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, you may have it deal damage to any target equal to the number of land cards in your graveyard.
SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X
SVar:X:Count$TypeInYourYard.Land
Oracle:When Ruination Rioter dies, you may have it deal damage to any target equal to the number of land cards in your graveyard.
Name:Segovian Angel
ManaCost:W
Types:Creature Angel
PT:1/1
K:Flying
K:Vigilance
Oracle:Flying, vigilance
Name:Sword of Sinew and Steel
ManaCost:3
Types:Artifact Equipment
K:Equip:2
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 2 | AddSVar$ SwordOfSinewAndSteelCE | AddKeyword$ Protection from black & Protection from red | Description$ Equipped creature gets +2/+2 and has protection from black and from red.
T:Mode$ DamageDone | ValidSource$ Creature.EquippedBy | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDestroyPlaneswalker | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals combat damage to a player, destroy up to one target planeswalker and up to one target artifact.
SVar:TrigDestroyPlaneswalker:DB$ Destroy | ValidTgts$ Planeswalker | TgtPrompt$ Select target planeswalker | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DestroyArtifact | SpellDescription$ Destroy up to one target planeswalker.
SVar:DestroyArtifact:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | TargetMin$ 0 | TargetMax$ 1 | SpellDescription$ Destroy up to one target artifact.
SVar:SwordOfSinewAndSteelCE:SVar:MustBeBlocked:AttackingPlayerConservative
Oracle:Equipped creature gets +2/+2 and has protection from white and from blue.\nWhenever equipped creature deals combat damage to a player, destroy up to one target planeswalker and up to one target artifact.\nEquip {2}
\ No newline at end of file
Name:Sword of Truth and Justice
ManaCost:3
Types:Artifact Equipment
K:Equip:2
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 2 | AddSVar$ SwordOfTruthAndJusticeCE | AddKeyword$ Protection from white & Protection from blue | Description$ Equipped creature gets +2/+2 and has protection from white and from blue.
T:Mode$ DamageDone | ValidSource$ Creature.EquippedBy | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals combat damage to a player, put a +1/+1 counter on a creature you control, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBProliferate | SpellDescription$ Put a +1/+1 counter on target creature you control and then proliferate.
SVar:DBProliferate:DB$ Proliferate
DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters
SVar:SwordOfTruthAndJusticeCE:SVar:MustBeBlocked:AttackingPlayerConservative
Oracle:Equipped creature gets +2/+2 and has protection from white and from blue.\nWhenever equipped creature deals combat damage to a player, put a +1/+1 counter on a creature you control, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)\nEquip {2}
\ No newline at end of file
Name:Talisman of Conviction
ManaCost:2
Types:Artifact
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Mana | Cost$ T | Produced$ R | SubAbility$ DBPain | SpellDescription$ Add {R}. CARDNAME deals 1 damage to you.
A:AB$ Mana | Cost$ T | Produced$ W | SubAbility$ DBPain | SpellDescription$ Add {W}. CARDNAME deals 1 damage to you.
SVar:DBPain:DB$DealDamage | NumDmg$ 1 | Defined$ You
Oracle:{T}: Add {C}.\n{T}: Add {R} or {W}. Talisman of Conviction deals 1 damage to you.
\ No newline at end of file
Name:Talisman of Creativity
ManaCost:2
Types:Artifact
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Mana | Cost$ T | Produced$ U | SubAbility$ DBPain | SpellDescription$ Add {U}. CARDNAME deals 1 damage to you.
A:AB$ Mana | Cost$ T | Produced$ R | SubAbility$ DBPain | SpellDescription$ Add {R}. CARDNAME deals 1 damage to you.
SVar:DBPain:DB$DealDamage | NumDmg$ 1 | Defined$ You
AI:RemoveDeck:Random
Oracle:{T}: Add {C}.\n{T}: Add {U} or {R}. Talisman of Creativity deals 1 damage to you.
Name:Talisman of Curiosity
ManaCost:2
Types:Artifact
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Mana | Cost$ T | Produced$ U | SubAbility$ DBPain | SpellDescription$ Add {U}. CARDNAME deals 1 damage to you.
A:AB$ Mana | Cost$ T | Produced$ G | SubAbility$ DBPain | SpellDescription$ Add {G}. CARDNAME deals 1 damage to you.
SVar:DBPain:DB$DealDamage | NumDmg$ 1 | Defined$ You
AI:RemoveDeck:Random
Oracle:{T}: Add {C}.\n{T}: Add {G} or {U}. Talisman of Curiosity deals 1 damage to you.
Name:Talisman of Hierarchy
ManaCost:2
Types:Artifact
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Mana | Cost$ T | Produced$ W | SubAbility$ DBPain | SpellDescription$ Add {W}. CARDNAME deals 1 damage to you.
A:AB$ Mana | Cost$ T | Produced$ B | SubAbility$ DBPain | SpellDescription$ Add {B}. CARDNAME deals 1 damage to you.
SVar:DBPain:DB$DealDamage | NumDmg$ 1 | Defined$ You
Oracle:{T}: Add {C}.\n{T}: Add {W} or {B}. Talisman of Hierarchy deals 1 damage to you.
Name:Talisman of Resilience
ManaCost:2
Types:Artifact
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Mana | Cost$ T | Produced$ B | SubAbility$ DBPain | SpellDescription$ Add {B}. CARDNAME deals 1 damage to you.
A:AB$ Mana | Cost$ T | Produced$ G | SubAbility$ DBPain | SpellDescription$ Add {G}. CARDNAME deals 1 damage to you.
SVar:DBPain:DB$DealDamage | NumDmg$ 1 | Defined$ You
Oracle:{T}: Add {C}.\n{T}: Add {B} or {G}. Talisman of Resilience deals 1 damage to you.
Name:Weather the Storm
ManaCost:1 G
Types:Instant
A:SP$ GainLife | Cost$ 1 G | LifeAmount$ 3 | SpellDescription$ You gain 3 life.
K:Storm
Oracle:You gain 3 life.\nStorm (When you cast this spell, copy it for each spell cast before it this turn. You may choose new targets for the copies.)
Name:Webweaver Changeling
ManaCost:3 G G
Types:Creature Shapeshifter
PT:3/5
K:Changeling
K:Reach
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | IsPresent$ Creature.YouCtrl | PresentCompare$ GE3 | PresentZone$ Graveyard | TriggerDescription$ When CARDNAME enters the battlefield, if there are three or more creature cards in your graveyard, you gain 5 life.
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 5
SVar:PlayMain1:Random
Oracle:Changeling (This card is every creature type.)\nReach\nWhen Webweaver Changeling enters the battlefield, if there are three or more creature cards in your graveyard, you gain 5 life.
Name:Winds of Abandon
ManaCost:1 W
Types:Sorcery
A:SP$ ChangeZone | Cost$ 1 W | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | SubAbility$ DBGetLands | RememberLKI$ True | SpellDescription$ Exile target creature you don’t control. For each creature exiled this way, its controller searches their library for a basic land card. Those players put those cards onto the battlefield tapped, then shuffle their libraries.
A:SP$ ChangeZoneAll | Cost$ 4 W W | ChangeType$ Creature.YouDontCtrl | Origin$ Battlefield | Destination$ Exile | RememberLKI$ True | SubAbility$ DBRepeat | PrecostDesc$ Overload | CostDesc$ {4}{W}{W} | NonBasicSpell$ True | SpellDescription$ (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of "target" with "each.")
SVar:DBGetLandsAll:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBGetLandsOne | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:DBGetLandsOne:DB$ ChangeZone | Optional$ True | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ X | References$ X | DefinedPlayer$ Player.IsRemembered | ShuffleNonMandatory$ False
SVar:X:RememberedLKI$FilterControlledByRemembered_Number$1
Oracle:Exile target creature you don’t control. For each creature exiled this way, its controller searches their library for a basic land card. Those players put those cards onto the battlefield tapped, then shuffle their libraries.\nOverload {4}{W}{W} (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of “target” with “each.”)
\ No newline at end of file
Name:Yawgmoth, Thran Physician
ManaCost:2 B B
Types:Legendary Creature Human Cleric
PT:2/4
K:Protection from Humans
A:AB$ PutCounter | Cost$ PayLife<1> Sac<1/Creature.Other/another creature> | ValidTgts$ Creature | TgtPrompt$ Select target creature | IsCurse$ True | CounterType$ M1M1 | CounterNum$ 1 | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDraw | SpellDescription$ Put a -1/-1 counter on up to one target creature and draw a card.
SVar:DBDraw:DB$Draw | Defined$ You | NumCards$ 1
A:AB$ Proliferate | Cost$ B B Discard<1/Card> | SpellDescription$ Proliferate.
DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters
Oracle:Protection from Humans. \nPay 1 life, Sacrifice another creature: Put a -1/-1 counter on up to one target creature and draw a card. \n{B}{B}, Discard a card: Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
\ No newline at end of file
[metadata]
Name=SCG Con Cube 2018 December
[main]
1 Dauntless Bodyguard|DOM
1 Kytheon, Hero of Akros|ORI
1 Mardu Woe-Reaper|FRF
1 Mother of Runes|EMA
1 Skymarcher Aspirant|RIX
1 Student of Warfare|ROE
1 Thraben Inspector|SOI
1 Toolcraft Exemplar|KLD
1 Accorder Paladin|MBS
1 Adanto Vanguard|XLN
1 Containment Priest|UMA
1 Leonin Relic-Warder|C17
1 Remorseful Cleric|M19
1 Selfless Spirit|EMN
1 Stoneforge Mystic|WWK
1 Thalia, Guardian of Thraben|A25
1 Wall of Omens|EMA
1 Blade Splicer|MM3
1 Brimaz, King of Oreskos|BNG
1 Monastery Mentor|FRF
1 Thalia, Heretic Cathar|EMN
1 Hero of Bladehold|MBS
1 Palace Jailer|CN2
1 Restoration Angel|IMA
1 Angel of Invention|KLD
1 Baneslayer Angel|M11
1 Sun Titan|M12
1 Gideon, Ally of Zendikar|BFZ
1 Elspeth, Sun's Champion|THS
1 Porcelain Legionnaire|NPH
1 Path to Exile|MM3
1 Swords to Plowshares|A25
1 Disenchant|A25
1 Secure the Wastes|DTK
1 Balance|EMA
1 Declaration in Stone|SOI
1 Council's Judgment|CNS
1 Lingering Souls|MM3
1 Spectral Procession|MM2
1 Armageddon|A25
1 Ravages of War|PTK
1 Wrath of God|MPS_AKH
1 Terminus|MM3
1 Intangible Virtue|MM3
1 Journey to Nowhere|ZEN
1 Oblivion Ring|MM2
1 Conclave Tribunal|GRN
1 Jace, Vryn's Prodigy|ORI
1 Looter il-Kor|TSP
1 Phantasmal Image|MM3
1 Snapcaster Mage|UMA
1 Champion of Wits|HOU
1 Man-o'-War|A25
1 Nimble Obstructionist|HOU
1 Sea Gate Oracle|MM3
1 Spellseeker
1 Vendilion Clique|A25
1 Glen Elendra Archmage|UMA
1 Sower of Temptation|LRW
1 Venser, Shaper Savant|MM3
1 Whirler Rogue|ORI
1 Mulldrifter|MM2
1 Aetherling|DGM
1 Consecrated Sphinx|IMA
1 Jace, the Mind Sculptor|VMA
1 Phyrexian Metamorph|NPH
1 Torrential Gearhulk|MPS_KLD
1 Ancestral Recall|VMA
1 Brainstorm|A25
1 Spell Pierce|XLN
1 Counterspell|A25
1 Impulse|VIS
1 Jilt|APC
1 Mana Drain|IMA
1 Remand|MM2
1 Forbid|MPS_AKH
1 Thirst for Knowledge|MMA
1 Cryptic Command|IMA
1 Fact or Fiction|EMA
1 Force of Will|MPS_AKH
1 Mystic Confluence|C15
1 Condescend|IMA
1 Dig Through Time|UMA
1 Time Walk|VMA
1 Compulsive Research|MM3
1 Tinker|ULG
1 Bribery|8ED
1 Upheaval|VMA
1 Search for Azcanta|XLN
1 Opposition|MPS_AKH
1 Treachery|UDS
1 Blood Artist|EMA
1 Bloodghast|IMA
1 Dark Confidant|MM2
1 Kitesail Freebooter|XLN
1 Pack Rat|RTR
1 Zulaport Cutthroat|A25
1 Liliana, Heretical Healer|ORI
1 Ophiomancer|C13
1 Plaguecrafter|GRN
1 Vampire Nighthawk|MM3
1 Braids, Cabal Minion|EMA
1 Kalitas, Traitor of Ghet|OGW
1 Ravenous Chupacabra|A25
1 Custodi Lich|CN2
1 Doom Whisperer|GRN
1 Shriekmaw|UMA
1 Grave Titan|M12
1 Griselbrand|MM3
1 Liliana of the Veil|UMA
1 Liliana, the Last Hope|EMN
1 Entomb|UMA
1 Fatal Push|AER
1 Vampiric Tutor|EMA
1 Diabolic Edict|A25
1 Doom Blade|IMA
1 Go for the Throat|MBS
1 Dismember|MM2
1 Hero's Downfall|THS
1 Duress|M19
1 Inquisition of Kozilek|MM3
1 Reanimate|UMA
1 Thoughtseize|IMA
1 Collective Brutality|EMN
1 Demonic Tutor|UMA
1 Exhume|USG
1 Hymn to Tourach|EMA
1 Toxic Deluge|EMA
1 Damnation|MPS_AKH
1 Mind Twist|MPS_AKH
1 Animate Dead|EMA
1 Bitterblossom|UMA
1 Necromancy|VIS
1 Phyrexian Arena|CN2
1 Recurring Nightmare|TPR
1 Goblin Guide|MM3
1 Goblin Welder|ULG
1 Grim Lavamancer|M12
1 Monastery Swiftspear|IMA
1 Soul-Scar Mage|AKH
1 Zurgo Bellstriker|DTK
1 Earthshaker Khenra|HOU
1 Goblin Cratermaker|GRN
1 Hellspark Elemental|CFX
1 Kari Zev, Skyship Raider|AER
1 Mogg War Marshal|EMA
1 Young Pyromancer|UMA
1 Goblin Rabblemaster|M15
1 Legion Warboss|GRN
1 Rampaging Ferocidon|XLN
1 Flametongue Kavu|VMA
1 Hazoret the Fervent|AKH
1 Hellrider|MM3
1 Pia and Kiran Nalaar|ORI
1 Siege-Gang Commander|DOM
1 Thundermaw Hellkite|IMA
1 Zealous Conscripts|MM3
1 Inferno Titan|M12
1 Chandra, Torch of Defiance|KLD
1 Burst Lightning|MM2
1 Dead // Gone|PLC
1 Lightning Bolt|A25
1 Abrade|HOU
1 Ancient Grudge|MM3
1 Incinerate|M12
1 Smash to Smithereens|ORI
1 Risk Factor|GRN
1 Fireblast|VMA
1 Chain Lightning|MPS_AKH
1 Faithless Looting|UMA
1 Firebolt|EMA
1 Arc Trail|SOM
1 Molten Rain|MM3
1 Wheel of Fortune|VMA
1 Fiery Confluence|C15
1 Burning of Xinye|VMA
1 Wildfire|MM2
1 Goblin Bombardment|TPR
1 Sulfuric Vortex|EMA
1 Experimental Frenzy|GRN
1 Arbor Elf|A25
1 Birds of Paradise|CN2
1 Elvish Mystic|M15
1 Joraga Treespeaker|ROE
1 Llanowar Elves|DOM
1 Noble Hierarch|UMA
1 Duskwatch Recruiter|SOI
1 Fauna Shaman|UMA
1 Lotus Cobra|IMA
1 Rofellos, Llanowar Emissary|VMA
1 Sakura-Tribe Elder|CNS
1 Scavenging Ooze|MM3
1 Tarmogoyf|UMA
1 Wall of Blossoms|TPR
1 Eternal Witness|UMA
1 Manglehorn|AKH
1 Reclamation Sage|M19
1 Tireless Tracker|SOI
1 Oracle of Mul Daya|ZEN
1 Thrun, the Last Troll|MBS
1 Acidic Slime|M13
1 Deranged Hermit|VMA
1 Thragtusk|MM3
1 Primeval Titan|IMA
1 Avenger of Zendikar|WWK
1 Hornet Queen|M15
1 Craterhoof Behemoth|MM3
1 Woodfall Primus|UMA
1 Garruk Relentless|ISD
1 Garruk Wildspeaker|M11
1 Nissa, Worldwaker|M15
1 Beast Within|CN2
1 Farseek|M13
1 Cultivate|A25
1 Kodama's Reach|UMA
1 Natural Order|EMA
1 Green Sun's Zenith|EMA
1 Tooth and Nail|MMA
1 Fastbond|VMA
1 Survival of the Fittest|TPR
1 Sylvan Library|EMA
1 Song of the Dryads|CMA
1 Courser of Kruphix|A25
1 Geist of Saint Traft|ISD
1 Spell Queller|EMN
1 Teferi, Hero of Dominaria|DOM
1 Fractured Identity|C17
1 The Scarab God|HOU
1 Baleful Strix|EMA
1 Agony Warp|MM3
1 Daretti, Ingenious Iconoclast|CN2
1 Terminate|MM3
1 Kolaghan's Command|DTK
1 Dreadbore|RTR
1 Bloodbraid Elf|EMA
1 Dragonlord Atarka|DTK
1 Gaddock Teeg|UMA
1 Qasali Pridemage|ARB