Merge remote-tracking branch 'refs/remotes/magefree/master' into cradle-to-the-grave

This commit is contained in:
Jerrad Bieno 2016-03-12 23:10:07 -06:00
commit b2173a9b13
35 changed files with 1060 additions and 330 deletions

View file

@ -3052,7 +3052,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
public static boolean isSaveImagesToZip() {
return PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_SAVE_TO_ZIP, "false").equals("true");
return PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_SAVE_TO_ZIP, "true").equals("true");
}
private static void load(Preferences prefs, JCheckBox checkBox, String propName, String yesValue) {

View file

@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 9;
public final static String MAGE_VERSION_MINOR_PATCH = "v1";
public final static String MAGE_VERSION_MINOR_PATCH = "v2";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

@ -82,6 +82,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Boros Guildgate", ""));
cubeCards.add(new CardIdentity("Branching Bolt", ""));
cubeCards.add(new CardIdentity("Brute Force", ""));
cubeCards.add(new CardIdentity("Brute Strength", ""));
cubeCards.add(new CardIdentity("Burst Lightning", ""));
cubeCards.add(new CardIdentity("Butcher Ghoul", ""));
cubeCards.add(new CardIdentity("Cadaver Imp", ""));
@ -89,7 +90,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Calcite Snapper", ""));
cubeCards.add(new CardIdentity("Capsize", ""));
cubeCards.add(new CardIdentity("Carnivorous Death-Parrot", ""));
cubeCards.add(new CardIdentity("Carnophage", ""));
cubeCards.add(new CardIdentity("Cathodion", ""));
cubeCards.add(new CardIdentity("Cavern Harpy", ""));
cubeCards.add(new CardIdentity("Centaur Healer", ""));
@ -106,8 +106,10 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Coalition Honor Guard", ""));
cubeCards.add(new CardIdentity("Cogwork Librarian", ""));
cubeCards.add(new CardIdentity("Colossal Might", ""));
cubeCards.add(new CardIdentity("Comparative Analysis", ""));
cubeCards.add(new CardIdentity("Compulsive Research", ""));
cubeCards.add(new CardIdentity("Consume Strength", ""));
cubeCards.add(new CardIdentity("Corpse Churn", ""));
cubeCards.add(new CardIdentity("Corrupted Zendikon", ""));
cubeCards.add(new CardIdentity("Counterspell", ""));
cubeCards.add(new CardIdentity("Crippling Fatigue", ""));
@ -144,7 +146,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Eldrazi Skyspawner", ""));
cubeCards.add(new CardIdentity("Elephant Ambush", ""));
cubeCards.add(new CardIdentity("Elephant Guide", ""));
cubeCards.add(new CardIdentity("Enhanced Awareness", ""));
cubeCards.add(new CardIdentity("Epic Confrontation", ""));
cubeCards.add(new CardIdentity("Errant Ephemeron", ""));
cubeCards.add(new CardIdentity("Esper Cormorants", ""));
@ -152,15 +153,12 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Evincar's Justice", ""));
cubeCards.add(new CardIdentity("Evolution Charm", ""));
cubeCards.add(new CardIdentity("Evolving Wilds", ""));
cubeCards.add(new CardIdentity("Eye of Nowhere", ""));
cubeCards.add(new CardIdentity("Faceless Butcher", ""));
cubeCards.add(new CardIdentity("Faith's Fetters", ""));
cubeCards.add(new CardIdentity("Fall of the Hammer", ""));
cubeCards.add(new CardIdentity("Feat of Resistance", ""));
cubeCards.add(new CardIdentity("Feeling of Dread", ""));
cubeCards.add(new CardIdentity("Fellwar Stone", ""));
cubeCards.add(new CardIdentity("Fervent Cathar", ""));
cubeCards.add(new CardIdentity("Fireblast", ""));
cubeCards.add(new CardIdentity("Firebolt", ""));
cubeCards.add(new CardIdentity("Firefiend Elemental", ""));
cubeCards.add(new CardIdentity("Fireslinger", ""));
@ -181,6 +179,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Giant Growth", ""));
cubeCards.add(new CardIdentity("Gideon's Lawkeeper", ""));
cubeCards.add(new CardIdentity("Gideon's Reproach", ""));
cubeCards.add(new CardIdentity("Goblin Freerunner", ""));
cubeCards.add(new CardIdentity("Goblin Heelcutter", ""));
cubeCards.add(new CardIdentity("Gods Willing", ""));
cubeCards.add(new CardIdentity("Goldmeadow Harrier", ""));
@ -207,18 +206,20 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Incinerate", ""));
cubeCards.add(new CardIdentity("Inner-Flame Acolyte", ""));
cubeCards.add(new CardIdentity("Into the Roil", ""));
cubeCards.add(new CardIdentity("Isolation Zone", ""));
cubeCards.add(new CardIdentity("Izzet Chronarch", ""));
cubeCards.add(new CardIdentity("Izzet Guildgate", ""));
cubeCards.add(new CardIdentity("Jilt", ""));
cubeCards.add(new CardIdentity("Journey to Nowhere", ""));
cubeCards.add(new CardIdentity("Jungle Hollow", ""));
cubeCards.add(new CardIdentity("Jwar Isle Avenger", ""));
cubeCards.add(new CardIdentity("Kabuto Moth", ""));
cubeCards.add(new CardIdentity("Keldon Marauders", ""));
cubeCards.add(new CardIdentity("Khalni Garden", ""));
cubeCards.add(new CardIdentity("Kingpin's Pet", ""));
cubeCards.add(new CardIdentity("Kodama's Reach", ""));
cubeCards.add(new CardIdentity("Kor Skyfisher", ""));
cubeCards.add(new CardIdentity("Kozilek's Predator", ""));
cubeCards.add(new CardIdentity("Kozilek's Channeler", ""));
cubeCards.add(new CardIdentity("Krenko's Command", ""));
cubeCards.add(new CardIdentity("Krosan Tusker", ""));
cubeCards.add(new CardIdentity("Kruin Striker", ""));
@ -236,7 +237,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Loyal Pegasus", ""));
cubeCards.add(new CardIdentity("Lurking Automaton", ""));
cubeCards.add(new CardIdentity("Makeshift Mauler", ""));
cubeCards.add(new CardIdentity("Makindi Sliderunner", ""));
cubeCards.add(new CardIdentity("Mana Leak", ""));
cubeCards.add(new CardIdentity("Man-o'-War", ""));
cubeCards.add(new CardIdentity("Mardu Hordechief", ""));
@ -247,6 +247,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Maze of Ith", ""));
cubeCards.add(new CardIdentity("Mind Stone", ""));
cubeCards.add(new CardIdentity("Minotaur Skullcleaver", ""));
cubeCards.add(new CardIdentity("Mire's Malice", ""));
cubeCards.add(new CardIdentity("Miscalculation", ""));
cubeCards.add(new CardIdentity("Mishra's Factory", ""));
cubeCards.add(new CardIdentity("Mist Raven", ""));
@ -269,7 +270,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Ninja of the Deep Hours", ""));
cubeCards.add(new CardIdentity("Oblivion Ring", ""));
cubeCards.add(new CardIdentity("Okiba-Gang Shinobi", ""));
cubeCards.add(new CardIdentity("Omenspeaker", ""));
cubeCards.add(new CardIdentity("Orzhov Guildgate", ""));
cubeCards.add(new CardIdentity("Otherworldly Journey", ""));
cubeCards.add(new CardIdentity("Pacifism", ""));
@ -297,6 +297,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Pristine Talisman", ""));
cubeCards.add(new CardIdentity("Probe", ""));
cubeCards.add(new CardIdentity("Prophetic Prism", ""));
cubeCards.add(new CardIdentity("Pulse of Murasa", ""));
cubeCards.add(new CardIdentity("Putrid Leech", ""));
cubeCards.add(new CardIdentity("Pyrotechnics", ""));
cubeCards.add(new CardIdentity("Qasali Pridemage", ""));
@ -309,7 +310,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Ray of Command", ""));
cubeCards.add(new CardIdentity("Razorfin Hunter", ""));
cubeCards.add(new CardIdentity("Reckless Charge", ""));
cubeCards.add(new CardIdentity("Reclaim", ""));
cubeCards.add(new CardIdentity("Recoil", ""));
cubeCards.add(new CardIdentity("Remove Soul", ""));
cubeCards.add(new CardIdentity("Rend Flesh", ""));
@ -320,6 +320,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Rugged Highlands", ""));
cubeCards.add(new CardIdentity("Runed Servitor", ""));
cubeCards.add(new CardIdentity("Rushing River", ""));
cubeCards.add(new CardIdentity("Saddleback Lagac", ""));
cubeCards.add(new CardIdentity("Safehold Elite", ""));
cubeCards.add(new CardIdentity("Sakura-Tribe Elder", ""));
cubeCards.add(new CardIdentity("Sandsteppe Outcast", ""));
@ -329,6 +330,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Savage Surge", ""));
cubeCards.add(new CardIdentity("Scatter the Seeds", ""));
cubeCards.add(new CardIdentity("Scion of the Wild", ""));
cubeCards.add(new CardIdentity("Scion Summoner", ""));
cubeCards.add(new CardIdentity("Scoured Barrens", ""));
cubeCards.add(new CardIdentity("Scuzzback Marauders", ""));
cubeCards.add(new CardIdentity("Searing Blaze", ""));
@ -350,19 +352,16 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Skinthinner", ""));
cubeCards.add(new CardIdentity("Skirk Marauder", ""));
cubeCards.add(new CardIdentity("Skyknight Legionnaire", ""));
cubeCards.add(new CardIdentity("Skywinder Drake", ""));
cubeCards.add(new CardIdentity("Slash Panther", ""));
cubeCards.add(new CardIdentity("Slippery Bogle", ""));
cubeCards.add(new CardIdentity("Snakeform", ""));
cubeCards.add(new CardIdentity("Snap", ""));
cubeCards.add(new CardIdentity("Snuff Out", ""));
cubeCards.add(new CardIdentity("Soul Manipulation", ""));
cubeCards.add(new CardIdentity("Sparksmith", ""));
cubeCards.add(new CardIdentity("Sphere of the Suns", ""));
cubeCards.add(new CardIdentity("Spined Thopter", ""));
cubeCards.add(new CardIdentity("Splatter Thug", ""));
cubeCards.add(new CardIdentity("Staggershock", ""));
cubeCards.add(new CardIdentity("Stampeding Elk Herd", ""));
cubeCards.add(new CardIdentity("Stave Off", ""));
cubeCards.add(new CardIdentity("Stitched Drake", ""));
cubeCards.add(new CardIdentity("Stormfront Pegasus", ""));
@ -373,9 +372,11 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Sultai Scavenger", ""));
cubeCards.add(new CardIdentity("Suppression Bonds", ""));
cubeCards.add(new CardIdentity("Suq'Ata Lancer", ""));
cubeCards.add(new CardIdentity("Sweep Away", ""));
cubeCards.add(new CardIdentity("Swiftwater Cliffs", ""));
cubeCards.add(new CardIdentity("Sylvok Lifestaff", ""));
cubeCards.add(new CardIdentity("Tail Slash", ""));
cubeCards.add(new CardIdentity("Tajuru Pathwarden", ""));
cubeCards.add(new CardIdentity("Teetering Peaks", ""));
cubeCards.add(new CardIdentity("Temporal Isolation", ""));
cubeCards.add(new CardIdentity("Tenement Crasher", ""));
@ -399,15 +400,14 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Twin Bolt", ""));
cubeCards.add(new CardIdentity("Typhoid Rats", ""));
cubeCards.add(new CardIdentity("Ulamog's Crusher", ""));
cubeCards.add(new CardIdentity("Umara Entangler", ""));
cubeCards.add(new CardIdentity("Undying Evil", ""));
cubeCards.add(new CardIdentity("Unearth", ""));
cubeCards.add(new CardIdentity("Unmake", ""));
cubeCards.add(new CardIdentity("Unnatural Aggression", ""));
cubeCards.add(new CardIdentity("Vampire Envoy", ""));
cubeCards.add(new CardIdentity("Vampire Interloper", ""));
cubeCards.add(new CardIdentity("Vampire Lacerator", ""));
cubeCards.add(new CardIdentity("Vault Skirge", ""));
cubeCards.add(new CardIdentity("Vendetta", ""));
cubeCards.add(new CardIdentity("Veteran's Sidearm", ""));
cubeCards.add(new CardIdentity("Viashino Firstblade", ""));
cubeCards.add(new CardIdentity("Vines of Vastwood", ""));
cubeCards.add(new CardIdentity("Voidwielder", ""));
@ -436,8 +436,8 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Wrecking Ball", ""));
cubeCards.add(new CardIdentity("Yavimaya Elder", ""));
cubeCards.add(new CardIdentity("Yotian Soldier", ""));
cubeCards.add(new CardIdentity("Young Wolf", ""));
cubeCards.add(new CardIdentity("Youthful Knight", ""));
cubeCards.add(new CardIdentity("Zada's Commando", ""));
cubeCards.add(new CardIdentity("Zhur-Taa Swine", ""));
}
}

View file

@ -30,16 +30,15 @@ package mage.sets.antiquities;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.PhaseStep;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.common.TargetArtifactPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
@ -54,7 +53,9 @@ public class GateToPhyrexia extends CardImpl {
this.expansionSetCode = "ATQ";
// Sacrifice a creature: Destroy target artifact. Activate this ability only during your upkeep and only once each turn.
Ability ability = new GateToPhyrexiaAbility(new DestroyTargetEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(),
new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))),
1, new IsStepCondition(PhaseStep.UPKEEP, true));
ability.addTarget(new TargetArtifactPermanent());
this.addAbility(ability);
}
@ -68,32 +69,3 @@ public class GateToPhyrexia extends CardImpl {
return new GateToPhyrexia(this);
}
}
class GateToPhyrexiaAbility extends LimitedTimesPerTurnActivatedAbility {
public GateToPhyrexiaAbility(Effect effect, Cost cost) {
super(Zone.BATTLEFIELD, effect, cost);
}
public GateToPhyrexiaAbility(final GateToPhyrexiaAbility ability) {
super(ability);
}
@Override
public GateToPhyrexiaAbility copy() {
return new GateToPhyrexiaAbility(this);
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (!game.getActivePlayerId().equals(controllerId) || !PhaseStep.UPKEEP.equals(game.getStep().getType())) {
return false;
}
return super.canActivate(playerId, game);
}
@Override
public String getRule() {
return "Sacrifice a creature: Destroy target artifact. Activate this ability only during your upkeep and only once each turn.";
}
}

View file

@ -28,17 +28,12 @@
package mage.sets.championsofkamigawa;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.LookLibraryControllerEffect;
@ -49,6 +44,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
@ -67,11 +66,11 @@ public class BrutalDeceiver extends CardImpl {
this.toughness = new MageInt(2);
// {1}: Look at the top card of your library.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1)));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1)));
// {2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn.
Ability ability = new BrutalDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1,0,Duration.EndOfTurn), new ManaCostsImpl("{2}"));
ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(),Duration.EndOfTurn));
Ability ability = new BrutalDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}"));
ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn));
this.addAbility(ability);
}
@ -87,36 +86,36 @@ public class BrutalDeceiver extends CardImpl {
class BrutalDeceiverAbility extends LimitedTimesPerTurnActivatedAbility {
public BrutalDeceiverAbility(Zone zone, Effect effect, Cost cost) {
public BrutalDeceiverAbility(Zone zone, Effect effect, Cost cost) {
super(zone, effect, cost);
}
public BrutalDeceiverAbility(BrutalDeceiverAbility ability) {
public BrutalDeceiverAbility(BrutalDeceiverAbility ability) {
super(ability);
}
@Override
public BrutalDeceiverAbility copy() {
return new BrutalDeceiverAbility(this);
}
@Override
public BrutalDeceiverAbility copy() {
return new BrutalDeceiverAbility(this);
}
@Override
@Override
public boolean checkIfClause(Game game) {
Player player = game.getPlayer(this.getControllerId());
if (player != null) {
Cards cards = new CardsImpl();
Card card = player.getLibrary().getFromTop(game);
cards.add(card);
player.revealCards("Brutal Deceiver", cards, game);
if (card != null && card.getCardType().contains(CardType.LAND)) {
return true;
}
}
return false;
Player player = game.getPlayer(this.getControllerId());
if (player != null) {
Cards cards = new CardsImpl();
Card card = player.getLibrary().getFromTop(game);
cards.add(card);
player.revealCards("Brutal Deceiver", cards, game);
if (card != null && card.getCardType().contains(CardType.LAND)) {
return true;
}
}
return false;
}
@Override
@Override
public String getRule() {
return "{2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. Activate this ability only once each turn.";
return "{2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. Activate this ability only once each turn.";
}
}

View file

@ -29,14 +29,11 @@ package mage.sets.fifthedition;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.UntapEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
@ -53,7 +50,6 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/**
*
@ -77,8 +73,7 @@ public class InstillEnergy extends CardImpl {
Ability haste = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(asThough, AttachmentType.AURA, Duration.WhileOnBattlefield, "Enchanted creature can attack as though it had haste."));
this.addAbility(haste);
// {0}: Untap enchanted creature. Activate this ability only during your turn and only once each turn.
Ability gainedAbility = new LimitedTimesIfConditionActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new GenericManaCost(0), MyTurnCondition.getInstance(), 1);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, "{0}: Untap enchanted creature. Activate this ability only during your turn and only once each turn.")));
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new GenericManaCost(0), 1, MyTurnCondition.getInstance()));
}
public InstillEnergy(final InstillEnergy card) {
@ -118,104 +113,3 @@ class CanAttackAsThoughItHadHasteEnchantedEffect extends AsThoughEffectImpl {
return enchantment != null && enchantment.getAttachedTo() != null && enchantment.getAttachedTo().equals(objectId);
}
}
class LimitedTimesIfConditionActivatedAbility extends ActivateIfConditionActivatedAbility {
class ActivationInfo {
public int turnNum;
public int activationCounter;
public ActivationInfo(int turnNum, int activationCounter) {
this.turnNum = turnNum;
this.activationCounter = activationCounter;
}
}
private int maxActivationsPerTurn;
public LimitedTimesIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) {
this(zone, effect, cost, condition, 1);
}
public LimitedTimesIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition, int maxActivationsPerTurn) {
super(zone, effect, cost, condition);
this.maxActivationsPerTurn = maxActivationsPerTurn;
}
public LimitedTimesIfConditionActivatedAbility(LimitedTimesIfConditionActivatedAbility ability) {
super(ability);
this.maxActivationsPerTurn = ability.maxActivationsPerTurn;
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (super.canActivate(playerId, game)) {
ActivationInfo activationInfo = getActivationInfo(game);
return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn;
}
return false;
}
@Override
public boolean activate(Game game, boolean noMana) {
if (canActivate(this.controllerId, game)) {
if (super.activate(game, noMana)) {
ActivationInfo activationInfo = getActivationInfo(game);
if (activationInfo == null) {
activationInfo = new ActivationInfo(game.getTurnNum(), 1);
} else if (activationInfo.turnNum != game.getTurnNum()) {
activationInfo.turnNum = game.getTurnNum();
activationInfo.activationCounter = 1;
} else {
activationInfo.activationCounter++;
}
setActivationInfo(activationInfo, game);
return true;
}
}
return false;
}
@Override
public boolean resolve(Game game) {
return super.resolve(game);
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder(super.getRule());
sb.replace(sb.length() - 1, sb.length() - 1, " and "); //suppress super()'s final period
switch (maxActivationsPerTurn) {
case 1:
sb.append("only once");
break;
case 2:
sb.append("no more than twice");
break;
default:
sb.append("no more than ").append(CardUtil.numberToText(maxActivationsPerTurn)).append(" times");
}
sb.append(" each turn.");
return sb.toString();
}
@Override
public LimitedTimesIfConditionActivatedAbility copy() {
return new LimitedTimesIfConditionActivatedAbility(this);
}
private ActivationInfo getActivationInfo(Game game) {
Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game));
Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game));
if (turnNum == null || activationCount == null) {
return null;
}
return new ActivationInfo(turnNum, activationCount);
}
private void setActivationInfo(ActivationInfo activationInfo, Game game) {
game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum);
game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter);
}
}

View file

@ -28,10 +28,6 @@
package mage.sets.innistrad;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Abilities;
import mage.abilities.Ability;
@ -40,13 +36,18 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -67,32 +68,33 @@ public class ManorGargoyle extends CardImpl {
this.toughness = new MageInt(4);
this.addAbility(DefenderAbility.getInstance());
/*
TODO: Implement the dependency rule
613.7. Within a layer or sublayer, determining which order effects are applied in is sometimes done using a dependency system.
/*
613.7. Within a layer or sublayer, determining which order effects are applied in is sometimes done using a dependency system.
If a dependency exists, it will override the timestamp system.
613.7a An effect is said to depend on another if
(a) its applied in the same layer (and, if applicable, sublayer) as the other effect (see rules 613.1 and 613.3);
(b) applying the other would change the text or the existence of the first effect, what it applies to, or what
it does to any of the things it applies to; and
(c) neither effect is from a characteristic-defining ability or both effects are from characteristic-defining
613.7a An effect is said to depend on another if
(a) its applied in the same layer (and, if applicable, sublayer) as the other effect (see rules 613.1 and 613.3);
(b) applying the other would change the text or the existence of the first effect, what it applies to, or what
it does to any of the things it applies to; and
(c) neither effect is from a characteristic-defining ability or both effects are from characteristic-defining
abilities. Otherwise, the effect is considered to be independent of the other effect.
613.7b An effect dependent on one or more other effects waits to apply until just after all of those effects have been applied.
If multiple dependent effects would apply simultaneously in this way, theyre applied in timestamp order relative to each
other. If several dependent effects form a dependency loop, then this rule is ignored and the effects in the dependency
other. If several dependent effects form a dependency loop, then this rule is ignored and the effects in the dependency
loop are applied in timestamp order.
613.7c After each effect is applied, the order of remaining effects is reevaluated and may change if an effect that has not yet
been applied becomes dependent on or independent of one or more other effects that have not yet been applied.
*/
// Manor Gargoyle has indestructible as long as it has defender.
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), HasDefenderCondition.getInstance(), rule);
GainAbilitySourceEffect gainEffect = new GainAbilitySourceEffect(IndestructibleAbility.getInstance());
gainEffect.setDependedToType(DependencyType.LooseDefenderEffect);
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(gainEffect, HasDefenderCondition.getInstance(), rule);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// {1}: Until end of turn, Manor Gargoyle loses defender and gains flying.
Effect effect2 = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.EndOfTurn);
ContinuousEffect effect2 = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.EndOfTurn);
effect2.addDependencyType(DependencyType.LooseDefenderEffect);
effect2.setText("Until end of turn, {this} loses defender");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect2, new ManaCostsImpl("{1}"));
effect2 = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);

View file

@ -85,7 +85,7 @@ public class UndeadAlchemist extends CardImpl {
class UndeadAlchemistTriggeredAbility extends TriggeredAbilityImpl {
public UndeadAlchemistTriggeredAbility() {
super(Zone.BATTLEFIELD, new ExileTargetEffect(), true);
super(Zone.BATTLEFIELD, new ExileTargetEffect(), false);
this.addEffect(new CreateTokenEffect(new ZombieToken()));
}

View file

@ -32,9 +32,9 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
@ -48,6 +48,7 @@ import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
@ -68,16 +69,16 @@ public class EbonPraetor extends CardImpl {
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, put a -2/-2 counter on Ebon Praetor.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.M2M2.createInstance()), TargetController.YOU, false));
// Sacrifice a creature: Remove a -2/-2 counter from Ebon Praetor. If the sacrificed creature was a Thrull, put a +1/+0 counter on Ebon Praetor. Activate this ability only during your upkeep and only once each turn.
Ability ability = new EbonPraetorAbility(new RemoveCounterSourceEffect(CounterType.M2M2.createInstance()),
new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.M2M2.createInstance()),
new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))), 1, new IsStepCondition(PhaseStep.UPKEEP, true));
ability.addEffect(new EbonPraetorEffect());
this.addAbility(ability);
}
@ -92,37 +93,6 @@ public class EbonPraetor extends CardImpl {
}
}
class EbonPraetorAbility extends LimitedTimesPerTurnActivatedAbility {
public EbonPraetorAbility(Effect effect, Cost cost) {
super(Zone.BATTLEFIELD, effect, cost);
}
public EbonPraetorAbility(final EbonPraetorAbility ability) {
super(ability);
}
@Override
public EbonPraetorAbility copy() {
return new EbonPraetorAbility(this);
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (!game.getActivePlayerId().equals(controllerId) || !PhaseStep.UPKEEP.equals(game.getStep().getType())) {
return false;
}
return super.canActivate(playerId, game);
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder("");
sb.append(super.getRule()).append(" <i>Activate this ability only during your upkeep.</i>");
return sb.toString();
}
}
class EbonPraetorEffect extends OneShotEffect {
public EbonPraetorEffect() {

View file

@ -0,0 +1,68 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.mirage;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ColoredManaCost;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
* @author djbrez
*/
public class FetidHorror extends CardImpl {
public FetidHorror(UUID ownerId) {
super(ownerId, 21, "Fetid Horror", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.expansionSetCode = "MIR";
this.subtype.add("Shade");
this.subtype.add("Horror");
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// {B}: Fetid Horror gets +1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B)));
}
public FetidHorror(final FetidHorror card) {
super(card);
}
@Override
public FetidHorror copy() {
return new FetidHorror(this);
}
}

View file

@ -37,8 +37,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.common.FilterCreatureSpell;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
@ -74,11 +73,7 @@ public class CeaseFire extends CardImpl {
class CeaseFireEffect extends ContinuousRuleModifyingEffectImpl {
private static final FilterSpell filter = new FilterSpell();
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
private static final FilterCreatureSpell filter = new FilterCreatureSpell();
public CeaseFireEffect() {
super(Duration.EndOfTurn, Outcome.Detriment);
@ -94,11 +89,6 @@ class CeaseFireEffect extends ContinuousRuleModifyingEffectImpl {
return new CeaseFireEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
@ -115,9 +105,9 @@ class CeaseFireEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getFirstTarget())) {
MageObject object = game.getObject(event.getSourceId());
if (filter.match((Spell) object, game)) {
if (event.getPlayerId().equals(getTargetPointer().getFirst(game, source))) {
Spell spell = game.getStack().getSpell(event.getSourceId());
if (spell != null && filter.match(spell, game)) {
return true;
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.onslaught;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
/**
*
* @author djbrez
*/
public class ScreechingBuzzard extends CardImpl {
public ScreechingBuzzard(UUID ownerId) {
super(ownerId, 165, "Screeching Buzzard", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.expansionSetCode = "ONS";
this.subtype.add("Bird");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Screeching Buzzard dies, each opponent discards a card.
this.addAbility(new DiesTriggeredAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT), false));
}
public ScreechingBuzzard(final ScreechingBuzzard card) {
super(card);
}
@Override
public ScreechingBuzzard copy() {
return new ScreechingBuzzard(this);
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author djbrez
*/
public class WuSpy extends CardImpl {
public WuSpy(UUID ownerId) {
super(ownerId, 63, "Wu Spy", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.subtype.add("Rogue");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When Wu Spy enters the battlefield, look at the top two cards of target player's library. Put one of them into his or her graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new WuSpyEffect(), false);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
public WuSpy(final WuSpy card) {
super(card);
}
@Override
public WuSpy copy() {
return new WuSpy(this);
}
}
class WuSpyEffect extends OneShotEffect {
WuSpyEffect() {
super(Outcome.Exile);
this.staticText = "look at the top two cards of target player's library. Put one of them into his or her graveyard";
}
WuSpyEffect(final WuSpyEffect effect) {
super(effect);
}
@Override
public WuSpyEffect copy() {
return new WuSpyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (controller != null && opponent != null) {
Cards cards = new CardsImpl();
cards.addAll(opponent.getLibrary().getTopCards(game, 2));
if (!cards.isEmpty()) {
TargetCard target = new TargetCardInLibrary(new FilterCard("card to put into graveyard"));
controller.choose(Outcome.Benefit, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
controller.moveCards(card, Zone.GRAVEYARD, source, game);
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class ForsakenSanctuary extends CardImpl {
public ForsakenSanctuary(UUID ownerId) {
super(ownerId, 273, "Forsaken Sanctuary", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "SOI";
// Forsaken Sanctuary enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {W} or {B} to your mana pool.
this.addAbility(new WhiteManaAbility());
this.addAbility(new BlackManaAbility());
}
public ForsakenSanctuary(final ForsakenSanctuary card) {
super(card);
}
@Override
public ForsakenSanctuary copy() {
return new ForsakenSanctuary(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class FoulOrchard extends CardImpl {
public FoulOrchard(UUID ownerId) {
super(ownerId, 275, "Foul Orchard", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "SOI";
// Foul Orchard enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {B} or {G} to your mana pool.
this.addAbility(new BlackManaAbility());
this.addAbility(new GreenManaAbility());
}
public FoulOrchard(final FoulOrchard card) {
super(card);
}
@Override
public FoulOrchard copy() {
return new FoulOrchard(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class HighlandLake extends CardImpl {
public HighlandLake(UUID ownerId) {
super(ownerId, 277, "Highland Lake", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "SOI";
// Highland Lake enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {U} or {R} to your mana pool.
this.addAbility(new BlueManaAbility());
this.addAbility(new RedManaAbility());
}
public HighlandLake(final HighlandLake card) {
super(card);
}
@Override
public HighlandLake copy() {
return new HighlandLake(this);
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author fireshoes
*/
public class PiousEvangel extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("{this} or another creature");
private static final FilterControlledPermanent filter2 = new FilterControlledPermanent("another permanent");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter2.add(new AnotherPredicate());
}
public PiousEvangel(UUID ownerId) {
super(ownerId, 34, "Pious Evangel", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.expansionSetCode = "SOI";
this.subtype.add("Human");
this.subtype.add("Cleric");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.canTransform = true;
this.secondSideCard = new WaywardDisciple(ownerId);
// Whenever Pious Evangel or another creature enters the battlefield under your control, you gain 1 life.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter));
// {2}, {T}, Sacrifice another permanent: Transform Pious Evangel.
this.addAbility(new TransformAbility());
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2)));
this.addAbility(ability);
}
public PiousEvangel(final PiousEvangel card) {
super(card);
}
@Override
public PiousEvangel copy() {
return new PiousEvangel(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class StoneQuarry extends CardImpl {
public StoneQuarry(UUID ownerId) {
super(ownerId, 279, "Stone Quarry", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "SOI";
// Stone Quarry enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {R} or {W} to your mana pool.
this.addAbility(new RedManaAbility());
this.addAbility(new WhiteManaAbility());
}
public StoneQuarry(final StoneQuarry card) {
super(card);
}
@Override
public StoneQuarry copy() {
return new StoneQuarry(this);
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesThisOrAnotherCreatureTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetOpponent;
/**
*
* @author fireshoes
*/
public class WaywardDisciple extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
}
public WaywardDisciple(UUID ownerId) {
super(ownerId, 34, "Wayward Disciple", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "SOI";
this.subtype.add("Human");
this.subtype.add("Cleric");
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// this card is the second face of double-faced card
this.nightCard = true;
// Whenever Wayward Disciple or another creature you control dies, target opponent loses 1 life and you gain 1 life.
Ability ability = new DiesThisOrAnotherCreatureTriggeredAbility(new LoseLifeTargetEffect(1), false, filter);
ability.addTarget(new TargetOpponent());
Effect effect = new GainLifeEffect(1);
effect.setText("and you gain 1 life");
ability.addEffect(effect);
this.addAbility(ability);
}
public WaywardDisciple(final WaywardDisciple card) {
super(card);
}
@Override
public WaywardDisciple copy() {
return new WaywardDisciple(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class WoodlandStream extends CardImpl {
public WoodlandStream(UUID ownerId) {
super(ownerId, 282, "Woodland Stream", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "SOI";
// Woodland Stream enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {G} or {U} to your mana pool.
this.addAbility(new GreenManaAbility());
this.addAbility(new BlueManaAbility());
}
public WoodlandStream(final WoodlandStream card) {
super(card);
}
@Override
public WoodlandStream copy() {
return new WoodlandStream(this);
}
}

View file

@ -31,13 +31,14 @@ import java.util.UUID;
import mage.constants.*;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreatureSpell;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
/**
*
@ -68,7 +69,9 @@ public class SteelGolem extends CardImpl {
}
class SteelGolemEffect extends ContinuousRuleModifyingEffectImpl {
private static final FilterCreatureSpell filter = new FilterCreatureSpell();
public SteelGolemEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "You can't cast creature spells";
@ -84,15 +87,15 @@ class SteelGolemEffect extends ContinuousRuleModifyingEffectImpl {
}
@Override
public boolean apply(Game game, Ability source) {
return true;
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getPlayerId().equals(source.getControllerId())) {
MageObject object = game.getObject(event.getSourceId());
if (object.getCardType().contains(CardType.CREATURE)) {
if (event.getPlayerId().equals(source.getControllerId())) {
Spell spell = game.getStack().getSpell(event.getSourceId());
if (spell != null && filter.match(spell, game)) {
return true;
}
}
@ -100,4 +103,3 @@ class SteelGolemEffect extends ContinuousRuleModifyingEffectImpl {
}
}

View file

@ -28,11 +28,11 @@
package mage.sets.timeshifted;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.keyword.StormAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCardInLibrary;
@ -43,17 +43,15 @@ import mage.target.common.TargetCardInLibrary;
*/
public class Dragonstorm extends CardImpl {
private static final FilterPermanentCard filter = new FilterPermanentCard("Dragon permanent card");
static {
filter.add(new SubtypePredicate("Dragon"));
}
public Dragonstorm(UUID ownerId) {
super(ownerId, 60, "Dragonstorm", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{8}{R}");
this.expansionSetCode = "TSB";
public Dragonstorm(UUID ownerId) {
super(ownerId, 60, "Dragonstorm", Rarity.SPECIAL, new CardType[]{CardType.SORCERY}, "{8}{R}");
this.expansionSetCode = "TSB";
// Search your library for a Dragon permanent card and put it onto the battlefield. Then shuffle your library.
this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false));

View file

@ -0,0 +1,58 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package org.mage.test.cards.conditional;
import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class ConditionalContinuousEffectTest extends CardTestPlayerBase {
@Test
public void testManorGargoyle() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
addCard(Zone.BATTLEFIELD, playerA, "Manor Gargoyle");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: Until end of turn");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertTapped("Mountain", true);
assertAbility(playerA, "Manor Gargoyle", DefenderAbility.getInstance(), false);
assertAbility(playerA, "Manor Gargoyle", IndestructibleAbility.getInstance(), false);
}
}

View file

@ -186,4 +186,36 @@ public class ProgenitorMimicTest extends CardTestPlayerBase {
}
/**
* Deadbridge Chant returns the battlefield Progenitor Mimic, but it's copy
* effect doesn't applied. It's 0/0, game put it into graveyard.
*/
@Test
public void testDeadbridgeChant() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
// When Deadbridge Chant enters the battlefield, put the top ten cards of your library into your graveyard.
// At the beginning of your upkeep, choose a card at random in your graveyard. If it's a creature card, put it onto the battlefield. Otherwise, put it into your hand.
addCard(Zone.HAND, playerA, "Deadbridge Chant", 1); // {4}{B}{G}
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
// You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield except
// it gains "At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield
// that's a copy of this creature."
addCard(Zone.LIBRARY, playerA, "Progenitor Mimic", 10);
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deadbridge Chant");
setChoice(playerA, "Silvercoat Lion"); // Copied by Progenitor Mimic returned by Deadbridge Chant on upkeep of turn 3
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPermanentCount(playerA, "Deadbridge Chant", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 2);
assertPowerToughness(playerA, "Silvercoat Lion", 2, 2);
assertGraveyardCount(playerA, "Progenitor Mimic", 9);
}
}

View file

@ -36,56 +36,73 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
public class AttackRequirementTest extends CardTestPlayerBase {
@Test
public void testSimpleAttackRequirement() {
// Defender
// {G}: Wall of Tanglecord gains reach until end of turn. (It can block creatures with flying.)
addCard(Zone.BATTLEFIELD, playerA, "Wall of Tanglecord"); // 0/6
// Juggernaut attacks each turn if able.
// Juggernaut can't be blocked by Walls
addCard(Zone.BATTLEFIELD, playerB, "Juggernaut"); // 5/3
// Juggernaut should be forced to ttack
// Juggernaut should be forced to ttack
block(2, playerA, "Wall of Tanglecord", "Juggernaut"); // this block should'nt work because of Juggernauts restriction
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 15);
assertLife(playerA, 15);
assertLife(playerB, 20);
}
@Test
public void testAttackRequirementWithAttackRestriction() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
// Defender
// {G}: Wall of Tanglecord gains reach until end of turn. (It can block creatures with flying.)
addCard(Zone.BATTLEFIELD, playerA, "Wall of Tanglecord"); // 0/6
// Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you
addCard(Zone.HAND, playerA, "Ghostly Prison");
// Juggernaut attacks each turn if able.
// Juggernaut can't be blocked by Walls
addCard(Zone.BATTLEFIELD, playerB, "Juggernaut"); // 5/3
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ghostly Prison");
// Juggernaut is forced to attack but can't without paying the Ghostly Prison cost and don't has to pay the costs so no attack
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
}
/**
* Goblin Rabblemaster isn't forcing Goblins to attack.
*/
@Test
public void testAttackRequirementGoblinRabblemaster() {
// Other Goblin creatures you control attack each turn if able.
// At the beginning of combat on your turn, put a 1/1 red Goblin creature token with haste onto the battlefield.
// When Goblin Rabblemaster attacks, it gets +1/+0 until end of turn for each other attacking Goblin.
addCard(Zone.BATTLEFIELD, playerB, "Goblin Rabblemaster"); // 2/2
// Menace (This creature can't be blocked except by two or more creatures.)
addCard(Zone.BATTLEFIELD, playerB, "Boggart Brute"); // 3/2
attack(2, playerB, "Goblin Rabblemaster");
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20);
assertLife(playerA, 12); // got damage 1 from Token, 3 from Boggart Brute + 2 + 2 from Goblin Rabblemaster = 9
assertLife(playerB, 20);
}
}

View file

@ -2,7 +2,6 @@ package org.mage.test.cards.triggers.dies;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -40,12 +39,6 @@ public class BloodArtistTest extends CardTestPlayerBase {
assertLife(playerB, 17);
}
/**
* There is realy something wrong with sacrifice effects triggers. Had
* Zulaport Cutthroat on battlefield and tried Altar's Reap and Bone
* Splinters on it. Neither triggered ZC's abbility. Tried the same with
* Blood Artist on battlefield, same result - no trigger.
*/
@Test
public void testWithBoneSplinters() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
@ -73,7 +66,6 @@ public class BloodArtistTest extends CardTestPlayerBase {
}
@Test
@Ignore // not Fixed yet
public void testWithBoneSplinters2() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
// As an additional cost to cast Bone Splinters, sacrifice a creature.
@ -98,7 +90,6 @@ public class BloodArtistTest extends CardTestPlayerBase {
}
@Test
@Ignore // not Fixed yet
public void testWithBoneSplinters3() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
// As an additional cost to cast Bone Splinters, sacrifice a creature.

View file

@ -1,21 +1,19 @@
package org.mage.test.sets;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import mage.cards.Card;
import mage.cards.repository.CardScanner;
import mage.sets.FateReforged;
import mage.sets.MastersEditionII;
import mage.sets.MastersEditionIV;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.mage.test.serverside.base.MageTestBase;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
*
* @author nigelzor
@ -38,8 +36,9 @@ public class BoosterGenerationTest extends MageTestBase {
"Bloodstained Mire", "Flooded Strand", "Polluted Delta", "Windswept Heath", "Wooded Foothills");
List<Card> booster = FateReforged.getInstance().createBooster();
assertTrue(str(booster), contains(booster, tapland, "FRF") || contains(booster, fetchland, "KTK"));
assertFalse(str(booster), contains(booster, basics, null));
assertTrue(str(booster), contains(booster, tapland, "FRF") || contains(booster, fetchland, "KTK")
|| contains(booster, basics, null));
// assertFalse(str(booster), contains(booster, basics, null));
}
@Test

View file

@ -24,12 +24,12 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.abilities.common;
import java.util.UUID;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
@ -54,24 +54,33 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl {
}
private int maxActivationsPerTurn;
private Condition condition;
public LimitedTimesPerTurnActivatedAbility(Zone zone, Effect effect, Cost cost) {
this(zone, effect, cost, 1);
}
public LimitedTimesPerTurnActivatedAbility(Zone zone, Effect effect, Cost cost, int maxActivationsPerTurn) {
super(zone, effect, cost);
this.maxActivationsPerTurn = maxActivationsPerTurn;
this(zone, effect, cost, maxActivationsPerTurn, null);
}
public LimitedTimesPerTurnActivatedAbility(LimitedTimesPerTurnActivatedAbility ability) {
public LimitedTimesPerTurnActivatedAbility(Zone zone, Effect effect, Cost cost, int maxActivationsPerTurn, Condition condition) {
super(zone, effect, cost);
this.maxActivationsPerTurn = maxActivationsPerTurn;
this.condition = condition;
}
public LimitedTimesPerTurnActivatedAbility(final LimitedTimesPerTurnActivatedAbility ability) {
super(ability);
this.maxActivationsPerTurn = ability.maxActivationsPerTurn;
this.condition = ability.condition;
}
@Override
public boolean canActivate(UUID playerId, Game game) {
return super.canActivate(playerId, game) && hasMoreActivationsThisTurn(game);
return super.canActivate(playerId, game)
&& hasMoreActivationsThisTurn(game)
&& (condition == null || condition.apply(game, this));
}
private boolean hasMoreActivationsThisTurn(Game game) {
@ -86,13 +95,11 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl {
ActivationInfo activationInfo = getActivationInfo(game);
if (activationInfo == null) {
activationInfo = new ActivationInfo(game.getTurnNum(), 1);
} else if (activationInfo.turnNum != game.getTurnNum()) {
activationInfo.turnNum = game.getTurnNum();
activationInfo.activationCounter = 1;
} else {
if (activationInfo.turnNum != game.getTurnNum()) {
activationInfo.turnNum = game.getTurnNum();
activationInfo.activationCounter = 1;
} else {
activationInfo.activationCounter++;
}
activationInfo.activationCounter++;
}
setActivationInfo(activationInfo, game);
return true;
@ -109,7 +116,10 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl {
@Override
public String getRule() {
StringBuilder sb = new StringBuilder(super.getRule()).append(" Activate this ability ");
switch(maxActivationsPerTurn) {
if (condition != null) {
sb.append("only ").append(condition.toString()).append(" and ");
}
switch (maxActivationsPerTurn) {
case 1:
sb.append("only once");
break;
@ -127,6 +137,7 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl {
public LimitedTimesPerTurnActivatedAbility copy() {
return new LimitedTimesPerTurnActivatedAbility(this);
}
private ActivationInfo getActivationInfo(Game game) {
Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game));
Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game));
@ -135,7 +146,7 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl {
}
return new ActivationInfo(turnNum, activationCount);
}
private void setActivationInfo(ActivationInfo activationInfo, Game game) {
game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum);
game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter);

View file

@ -76,6 +76,10 @@ public interface ContinuousEffect extends Effect {
Set<DependencyType> getDependencyTypes();
void addDependencyType(DependencyType dependencyType);
void setDependedToType(DependencyType dependencyType);
@Override
void newId();

View file

@ -29,6 +29,7 @@ package mage.abilities.effects;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@ -71,7 +72,8 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
protected boolean affectedObjectsSet = false;
protected List<MageObjectReference> affectedObjectList = new ArrayList<>();
protected boolean temporary = false;
protected EnumSet<DependencyType> dependencyTypes;
protected EnumSet<DependencyType> dependencyTypes; // this effect has the dependencyTypes defined here
protected DependencyType dependendToType; // this effect is dependent to this type
/*
A Characteristic Defining Ability (CDA) is an ability that defines a characteristic of a card or token.
There are 3 specific rules that distinguish a CDA from other abilities.
@ -91,6 +93,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
this.order = 0;
this.effectType = EffectType.CONTINUOUS;
this.dependencyTypes = EnumSet.noneOf(DependencyType.class);
this.dependendToType = null;
}
public ContinuousEffectImpl(Duration duration, Layer layer, SubLayer sublayer, Outcome outcome) {
@ -188,12 +191,10 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
case PTChangingEffects_7:
this.affectedObjectsSet = true;
}
} else {
if (hasLayer(Layer.CopyEffects_1) || hasLayer(Layer.ControlChangingEffects_2) || hasLayer(Layer.TextChangingEffects_3)
|| hasLayer(Layer.TypeChangingEffects_4) || hasLayer(Layer.ColorChangingEffects_5) || hasLayer(Layer.AbilityAddingRemovingEffects_6)
|| hasLayer(Layer.PTChangingEffects_7)) {
this.affectedObjectsSet = true;
}
} else if (hasLayer(Layer.CopyEffects_1) || hasLayer(Layer.ControlChangingEffects_2) || hasLayer(Layer.TextChangingEffects_3)
|| hasLayer(Layer.TypeChangingEffects_4) || hasLayer(Layer.ColorChangingEffects_5) || hasLayer(Layer.AbilityAddingRemovingEffects_6)
|| hasLayer(Layer.PTChangingEffects_7)) {
this.affectedObjectsSet = true;
}
}
startingTurn = game.getTurnNum();
@ -275,6 +276,19 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
@Override
public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) {
if (dependendToType != null) {
// the dependent classes needs to be an enclosed class for dependent check of continuous effects
Set<UUID> dependentTo = null;
for (ContinuousEffect effect : allEffectsInLayer) {
if (effect.getDependencyTypes().contains(dependendToType)) {
if (dependentTo == null) {
dependentTo = new HashSet<>();
}
dependentTo.add(effect.getId());
}
}
return dependentTo;
}
return null;
}
@ -283,4 +297,14 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
return dependencyTypes;
}
@Override
public void addDependencyType(DependencyType dependencyType) {
dependencyTypes.add(dependencyType);
}
@Override
public void setDependedToType(DependencyType dependencyType) {
dependendToType = dependencyType;
}
}

View file

@ -63,7 +63,7 @@ public enum CardRepository {
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 43;
// raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 47;
private static final long CARD_CONTENT_VERSION = 48;
private final Random random = new Random();
private Dao<CardInfo, Object> cardDao;

View file

@ -46,5 +46,6 @@ public enum DependencyType {
BecomeMountain,
BecomePlains,
BecomeSwamp,
EnchantmentAddingRemoving;
EnchantmentAddingRemoving,
LooseDefenderEffect;
}

View file

@ -1278,6 +1278,7 @@ public abstract class GameImpl implements Game, Serializable {
if (executingRollback()) {
return;
}
getState().handleSimultaneousEvent(this); // needed here to handle triggers e.g. from paying costs like sacrificing a creatures before LKIShort is cleared
applyEffects();
}
if (isPaused()) {

View file

@ -56944,6 +56944,8 @@ Bygone Bishop|Shadows over Innistrad|8|R|{2}{W}|Creature - Spirit Cleric|2|3|Fly
Declaration in Stone|Shadows over Innistrad|12|R|{1}{W}|Sorcery|||Exile target creature and all other creatures its controller controls with the same name as that creature. That player investigates for each nontoken creature exiled this way.|
Eerie Interlude|Shadows over Innistrad|16|R|{2}{W}|Instant|||Exile any number of target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step.|
Expose Evil|Shadows over Innistrad|19|C|{1}{W}|Instant|||Tap up to two target creatures.$Investigate. <i>(Put a colorless Clue artifact token onto the battlefield with "{2}, Sacrifice this artifact: Draw a card.")</i>|
Pious Evangel|Shadows over Innistrad|34a|U|{2}{W}|Creature - Human Cleric|2|2|Whenever Pious Evangel or another creature enters the battlefield under your control, you gain 1 life.${2}, {T}, Sacrifice another permanent: Transform Pious Evangel.|
Wayward Disciple|Shadows over Innistrad|34b|U||Creature - Human Cleric|2|4|Whenever Wayward Disciple or another creature you control dies, target opponent loses 1 life and you gain 1 life.|
Reaper of Flight Moonsilver|Shadows over Innistrad|36|U|{3}{W}{W}|Creature - Angel|3|3|Flying$<i>Delirium</i> &mdash; Sacrifice another creature: Reaper of Flight Moonsilver gets +2/+1 until end of turn. Activate this ability only if there are four or more card types among cards in your graveyard.|
Thraben Inspector|Shadows over Innistrad|44|C|{W}|Creature - Human Soldier|1|2|When Thraben Inspector enters the battlefield, investigate. <i>(Put a colorless Clue artifact token onto the battlefield with "{2}, Sacrifice this artifact: Draw a card.")</i>|
Topplegeist|Shadows over Innistrad|45|U|{W}|Creature - Spirit|1|1|Flying$When Topplegeist enters the battlefield, tap target creature an opponent controls.$<i>Delirium</i> &mdash; At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, tap target creature that player controls.|
@ -57002,6 +57004,11 @@ Explosive Apparatus|Shadows over Innistrad|255|C|{1}|Artifact|||{3}, {T}, Sacrif
Magnifying Glass|Shadows over Innistrad|258|U|{3}|Artifact|||{T}: Add {C} to your mana pool.${4}, {T}: Investigate. <i>(Put a colorless Clue artifact token onto the battlefield with "{2}, Sacrifice this artifact: Draw a card.")</i>|
Shard of Broken Glass|Shadows over Innistrad|262|C|{1}|Artifact - Equipment|||Equipped creature gets +1/+0.$Whenever equipped creature attacks, you may put the top two cards of your library into your graveyard.$Equip {1} <i>({1}: Attach to target creature you control. Equip only as a sorcery.)</i>|
Tamiyo's Journal|Shadows over Innistrad|265|R|{5}|Legendary Artifact|||At the beginning of your upkeep, investigate. <i>(Put a colorless Clue artifact token onto the battlefield with "{2}, Sacrifice this artifact: Draw a card.")</i>${T}, Sacrifice three Clues: Search your library for a card and put that card into your hand. Then shuffle your library.|
Forsaken Sanctuary|Shadows over Innistrad|273|U||Land|||Forsaken Sanctuary enters the battlefield tapped.${T}: Add {W} or {B} to your mana pool.|
Foul Orchard|Shadows over Innistrad|275|U||Land|||Foul Orchard enters the battlefield tapped.${T}: Add {B} or {G} to your mana pool.|
Highland Lake|Shadows over Innistrad|277|U||Land|||Highland Lake enters the battlefield tapped.${T}: Add {U} or {R} to your mana pool.|
Stone Quarry|Shadows over Innistrad|279|U||Land|||Stone Quarry enters the battlefield tapped.${T}: Add {R} or {W} to your mana pool.|
Woodland Stream|Shadows over Innistrad|282|U||Land|||Woodland Stream enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.|
Warped Landscape|Shadows over Innistrad|280|C||Land|||{T}: Add {C} to your mana pool.${2}, {T}, Sacrifice Warped Landscape: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.|
Force of Will|Eternal Masters|49|M|{3}{U}{U}|Instant|||You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.$Counter target spell.|
Wasteland|Eternal Masters|248|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice Wasteland: Destroy target nonbasic land.|

View file

@ -66,6 +66,9 @@ git log 51a0d8a4b2f53ea67d21f771acc533b610a02e0c..head --diff-filter=A --name-st
since 1.4.9v1
git log 6d4a3bac288e9f3aff84d878c9816f89500a67af..head --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
since 1.4.9v2
git log d818fadf52ff2e4e4df2142d0eb98a48e8cddb86..head --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
3. Copy added_cards.txt to trunk\Utils folder
4. Run script:
> perl extract_in_wiki_format.perl