Merge remote-tracking branch 'refs/remotes/magefree/master'

This commit is contained in:
CountAndromalius 2016-07-12 12:51:54 -03:00
commit d3510d378a
108 changed files with 8838 additions and 6346 deletions

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -114,66 +114,19 @@ public class MythicspoilerComSource implements CardImageSource {
for (String setName : setNames.split("\\^")) {
String URLSetName = URLEncoder.encode(setName, "UTF-8");
String baseUrl = "http://mythicspoiler.com/" + URLSetName + "/";
String urlDocument;
Document doc;
if (proxyType.equals(ProxyType.NONE)) {
urlDocument = baseUrl;
doc = Jsoup.connect(urlDocument).get();
} else {
String proxyServer = prefs.get("proxyAddress", "");
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
URL url = new URL(baseUrl);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
uc.connect();
Map<String, String> pageLinks = getSetLinksFromPage(cardSet, aliasesStart, prefs, proxyType, baseUrl, baseUrl);
setLinks.putAll(pageLinks);
String line;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((line = in.readLine()) != null) {
tmp.append(line);
}
doc = Jsoup.parse(String.valueOf(tmp));
// try to download images for double-faced cards
try {
String doubleFacedUrl = baseUrl + "dfc.html";
pageLinks = getSetLinksFromPage(cardSet, aliasesStart, prefs, proxyType, baseUrl, doubleFacedUrl);
setLinks.putAll(pageLinks);
}
Elements cardsImages = doc.select("img[src^=cards/]"); // starts with cards/
if (!aliasesStart.isEmpty()) {
for (String text : aliasesStart) {
cardsImages.addAll(doc.select("img[src^=" + text + "]"));
}
catch (Exception ex) {
// that's ok if we cannot download double-faced cards for some sets
}
if (cardsImages.isEmpty()) {
break;
}
for (Element cardsImage : cardsImages) {
String cardLink = cardsImage.attr("src");
String cardName = null;
if (cardLink.startsWith("cards/") && cardLink.endsWith(".jpg")) {
cardName = cardLink.substring(6, cardLink.length() - 4);
} else if (aliasesStart.contains(cardLink)) {
cardName = cardLink.substring(0, cardLink.length() - 4);;
}
if (cardName != null && !cardName.isEmpty()) {
if (cardNameAliases.containsKey(cardSet + "-" + cardName)) {
cardName = cardNameAliases.get(cardSet + "-" + cardName);
} else {
if (cardName.endsWith("1") || cardName.endsWith("2") || cardName.endsWith("3") || cardName.endsWith("4") || cardName.endsWith("5")) {
if (!cardName.startsWith("forest")
&& !cardName.startsWith("swamp")
&& !cardName.startsWith("mountain")
&& !cardName.startsWith("island")
&& !cardName.startsWith("plains")) {
cardName = cardName.substring(0, cardName.length() - 1);
}
}
}
setLinks.put(cardName, baseUrl + cardLink);
}
}
}
} catch (IOException ex) {
@ -182,6 +135,71 @@ public class MythicspoilerComSource implements CardImageSource {
return setLinks;
}
private Map<String, String> getSetLinksFromPage(String cardSet, Set<String> aliasesStart, Preferences prefs,
ProxyType proxyType, String baseUrl, String pageUrl) throws IOException {
Map<String, String> pageLinks = new HashMap<>();
String urlDocument;
Document doc;
if (proxyType.equals(ProxyType.NONE)) {
urlDocument = pageUrl;
doc = Jsoup.connect(urlDocument).get();
} else {
String proxyServer = prefs.get("proxyAddress", "");
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
URL url = new URL(pageUrl);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
uc.connect();
String line;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((line = in.readLine()) != null) {
tmp.append(line);
}
doc = Jsoup.parse(String.valueOf(tmp));
}
Elements cardsImages = doc.select("img[src^=cards/]"); // starts with cards/
if (!aliasesStart.isEmpty()) {
for (String text : aliasesStart) {
cardsImages.addAll(doc.select("img[src^=" + text + "]"));
}
}
for (Element cardsImage : cardsImages) {
String cardLink = cardsImage.attr("src");
String cardName = null;
if (cardLink.startsWith("cards/") && cardLink.endsWith(".jpg")) {
cardName = cardLink.substring(6, cardLink.length() - 4);
} else if (aliasesStart.contains(cardLink)) {
cardName = cardLink.substring(0, cardLink.length() - 4);
;
}
if (cardName != null && !cardName.isEmpty()) {
if (cardNameAliases.containsKey(cardSet + "-" + cardName)) {
cardName = cardNameAliases.get(cardSet + "-" + cardName);
} else {
if (cardName.endsWith("1") || cardName.endsWith("2") || cardName.endsWith("3") || cardName.endsWith("4") || cardName.endsWith("5")) {
if (!cardName.startsWith("forest")
&& !cardName.startsWith("swamp")
&& !cardName.startsWith("mountain")
&& !cardName.startsWith("island")
&& !cardName.startsWith("plains")) {
cardName = cardName.substring(0, cardName.length() - 1);
}
}
}
pageLinks.put(cardName, baseUrl + cardLink);
}
}
return pageLinks;
}
@Override
public String generateURL(CardDownloadData card) throws Exception {
Integer collectorId = card.getCollectorId();

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-common</artifactId>

View file

@ -40,8 +40,8 @@ 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 = 12;
public final static String MAGE_VERSION_MINOR_PATCH = "v0";
public final static int MAGE_VERSION_PATCH = 13;
public final static String MAGE_VERSION_MINOR_PATCH = "v1";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-deck-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-freeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-ai</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-player-human</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-tournament-sealed</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-server</artifactId>

View file

@ -78,6 +78,7 @@
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
@ -106,6 +107,7 @@
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2016"/>
<draftCube name="The Peasant's Toolbox (800 cards)" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com (502 cards)" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGCube"/>
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.CubeFromDeck"/>
</draftCubes>
<deckTypes>
<deckType name="Constructed - Standard" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Standard"/>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -40,12 +40,15 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTargets;
@ -105,7 +108,18 @@ class EerieInterludeEffect extends OneShotEffect {
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (((Permanent) exiled).getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
}
else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}

View file

@ -34,7 +34,7 @@ import mage.abilities.keyword.MadnessAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCreatureOrPlayer;
import mage.target.common.TargetCreaturePermanent;
/**
*
@ -48,7 +48,8 @@ public class AlchemistsGreeting extends CardImpl {
// Alchemist's Greeting deals 4 damage to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Madness {1}{R}
this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}")));
}

View file

@ -1,87 +1,103 @@
/*
* 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.eldritchmoon;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.GainLifeTargetEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.keyword.EscalateAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterAttackingCreature;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
/**
*
* @author emerald000
*/
public class BlessedAlliance extends CardImpl {
public BlessedAlliance(UUID ownerId) {
super(ownerId, 13, "Blessed Alliance", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.expansionSetCode = "EMN";
// Escalate {2}
this.addAbility(new EscalateAbility(new GenericManaCost(2)));
// Choose one or more
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(3);
// Target player gains 4 life.
this.getSpellAbility().addEffect(new GainLifeTargetEffect(4));
this.getSpellAbility().addTarget(new TargetPlayer());
// Untap up to two target creatures.
Mode mode = new Mode();
mode.getEffects().add(new UntapTargetEffect());
mode.getTargets().add(new TargetCreaturePermanent(0, 2));
this.getSpellAbility().addMode(mode);
// Target opponent sacrifices an attacking creature.
mode = new Mode();
mode.getEffects().add(new SacrificeEffect(new FilterAttackingCreature(), 1, "Target player"));
mode.getTargets().add(new TargetOpponent());
this.getSpellAbility().addMode(mode);
}
public BlessedAlliance(final BlessedAlliance card) {
super(card);
}
@Override
public BlessedAlliance copy() {
return new BlessedAlliance(this);
}
}
/*
* 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.eldritchmoon;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeTargetEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.keyword.EscalateAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.FilterPlayer;
import mage.filter.common.FilterAttackingCreature;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.other.PlayerPredicate;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author emerald000
*/
public class BlessedAlliance extends CardImpl {
private static final FilterPlayer filterSacrifice = new FilterPlayer("opponent to sacrifice an attacking creature");
private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creatures to untap");
private static final FilterPlayer filterGainLife = new FilterPlayer("player to gain life");
static {
filterSacrifice.add(new PlayerPredicate(TargetController.OPPONENT));
}
public BlessedAlliance(UUID ownerId) {
super(ownerId, 13, "Blessed Alliance", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.expansionSetCode = "EMN";
// Escalate {2}
this.addAbility(new EscalateAbility(new GenericManaCost(2)));
// Choose one or more
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(3);
// Target player gains 4 life.
Effect effect = new GainLifeTargetEffect(4);
effect.setText("Target player gains 4 life");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer(1, 1, false, filterGainLife));
// Untap up to two target creatures.
Mode mode = new Mode();
effect = new UntapTargetEffect();
effect.setText("Untap up to two target creatures");
mode.getEffects().add(effect);
mode.getTargets().add(new TargetCreaturePermanent(0, 2, filterCreature, false));
this.getSpellAbility().addMode(mode);
// Target opponent sacrifices an attacking creature.
mode = new Mode();
mode.getEffects().add(new SacrificeEffect(new FilterAttackingCreature(), 1, "Target opponent"));
mode.getTargets().add(new TargetPlayer(1, 1, false, filterSacrifice));
this.getSpellAbility().addMode(mode);
}
public BlessedAlliance(final BlessedAlliance card) {
super(card);
}
@Override
public BlessedAlliance copy() {
return new BlessedAlliance(this);
}
}

View file

@ -30,7 +30,8 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.EscalateAbility;
import mage.abilities.keyword.FirstStrikeAbility;
@ -38,6 +39,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
@ -46,24 +48,32 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class BorrowedHostility extends CardImpl {
private static final FilterCreaturePermanent filterBoost = new FilterCreaturePermanent("creature to get +3/+0");
private static final FilterCreaturePermanent filterFirstStrike = new FilterCreaturePermanent("creature to gain first strike");
public BorrowedHostility(UUID ownerId) {
super(ownerId, 121, "Borrowed Hostility", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}");
this.expansionSetCode = "EMN";
// Escalate {3}
this.addAbility(new EscalateAbility(new ManaCostsImpl<>("{3}")));
// Choose one or both &mdash;
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(2);
// Target creature gets +3/+0 until end of turn.;
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BoostControlledEffect(3, 0, Duration.EndOfTurn));
Effect effect = new BoostTargetEffect(3, 0, Duration.EndOfTurn);
effect.setText("Target creature gets +3/+0 until end of turn");
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterBoost));
this.getSpellAbility().addEffect(effect);
// Target creature gains first strike until end of turn.
Mode mode = new Mode();
mode.getEffects().add(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn));
mode.getTargets().add(new TargetCreaturePermanent());
effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
effect.setText("Target creature gains first strike until end of turn");
mode.getEffects().add(effect);
mode.getTargets().add(new TargetCreaturePermanent(filterFirstStrike));
this.getSpellAbility().addMode(mode);
}

View file

@ -37,7 +37,7 @@ import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
@ -52,7 +52,7 @@ import mage.game.stack.Spell;
*
* @author LevelX2
*/
public class BriselaVoiceOfNightmares extends CardImpl {
public class BriselaVoiceOfNightmares extends MeldCard {
public BriselaVoiceOfNightmares(UUID ownerId) {
super(ownerId, 15, "Brisela, Voice of Nightmares", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "");
@ -67,12 +67,16 @@ public class BriselaVoiceOfNightmares extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// Your opponents can't cast spells with converted mana cost 3 or less.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BriselaVoiceOfNightmaresCantCastEffect()));
}

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
@ -70,7 +71,9 @@ public class BrunaTheFadingLight extends CardImpl {
this.toughness = new MageInt(7);
// When you cast Bruna, the Fading Light, you may return target Angel or Human creature card from your graveyard to the battlefield.
Ability ability = new CastSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true);
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
effect.setText("you may return target Angel or Human creature card from your graveyard to the battlefield");
Ability ability = new CastSourceTriggeredAbility(effect, true);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);

View file

@ -36,7 +36,7 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
@ -46,7 +46,7 @@ import mage.filter.common.FilterControlledCreaturePermanent;
*
* @author LevelX2
*/
public class ChitteringHost extends CardImpl {
public class ChitteringHost extends MeldCard {
public ChitteringHost(UUID ownerId) {
super(ownerId, 96, "Chittering Host", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "");
@ -57,18 +57,21 @@ public class ChitteringHost extends CardImpl {
this.toughness = new MageInt(6);
this.nightCard = true; // Meld card
// Haste
this.addAbility(HasteAbility.getInstance());
// Menace <i>(This creature can't be blocked except by two or more creatures.
this.addAbility(new MenaceAbility());
// When Chittering Host enters the battlefield, other creatures you control get +1/+0 and gain menace until end of turn.
Effect effect = new BoostControlledEffect(1, 0, Duration.EndOfTurn, true);
effect.setText("other creatures you control get +1/+0");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
effect = new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, new FilterControlledCreaturePermanent("other creatures"), true);
effect.setText("and gain menace until end of turn");
ability.addEffect(effect);
this.addAbility(ability);
}
public ChitteringHost(final ChitteringHost card) {

View file

@ -30,6 +30,7 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -77,7 +78,9 @@ public class CollectiveEffort extends CardImpl {
this.expansionSetCode = "EMN";
// Escalate &mdash; Tap an untapped creature you control.
this.addAbility(new EscalateAbility(new TapTargetCost(new TargetControlledCreaturePermanent(filterUntapped))));
Cost cost = new TapTargetCost(new TargetControlledCreaturePermanent(filterUntapped));
cost.setText("&mdash; Tap an untapped creature you control");
this.addAbility(new EscalateAbility(cost));
// Choose one or more &mdash;
this.getSpellAbility().getModes().setMinModes(1);

View file

@ -59,7 +59,6 @@ public class DistemperOfTheBlood extends CardImpl {
effect.setText("and gains trample until end of turn");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
// Madness {R}
this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{R}")));

View file

@ -58,7 +58,7 @@ import mage.players.Player;
*/
public class DocentOfPerfection extends CardImpl {
private static final FilterSpell filterSpell = new FilterSpell("instant or sorcery spell");
private static final FilterSpell filterSpell = new FilterSpell("an instant or sorcery spell");
static {
filterSpell.add(Predicates.or(

View file

@ -56,7 +56,8 @@ public class DrogskolShieldmate extends CardImpl {
this.addAbility(FlashAbility.getInstance());
// When Drogskol Shieldmate enters the battlefield, other creatures you control get +0/+1 until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostControlledEffect(0, 1, Duration.EndOfTurn, new FilterCreaturePermanent(), true), false));
this.addAbility(new EntersBattlefieldTriggeredAbility(
new BoostControlledEffect(0, 1, Duration.EndOfTurn, new FilterCreaturePermanent("creatures"), true), false));
}
public DrogskolShieldmate(final DrogskolShieldmate card) {

View file

@ -1,78 +1,78 @@
/*
* 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.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.EmergeAbility;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.target.TargetPermanent;
/**
*
* @author emerald000
*/
public class ElderDeepFiend extends CardImpl {
public ElderDeepFiend(UUID ownerId) {
super(ownerId, 5, "Elder Deep-Fiend", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{8}");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Octopus");
this.power = new MageInt(5);
this.toughness = new MageInt(6);
// Flash
this.addAbility(FlashAbility.getInstance());
// Emerge {5}{U}{U}
this.addAbility(new EmergeAbility(this, new ManaCostsImpl<>("{5}{U}{U}")));
// When you cast Elder Deep-Fiend, tap up to four target permanents.
Ability ability = new CastSourceTriggeredAbility(new TapTargetEffect());
ability.addTarget(new TargetPermanent(0, 4, new FilterPermanent("permanents to tap"), false));
this.addAbility(ability);
}
public ElderDeepFiend(final ElderDeepFiend card) {
super(card);
}
@Override
public ElderDeepFiend copy() {
return new ElderDeepFiend(this);
}
}
/*
* 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.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.EmergeAbility;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.target.TargetPermanent;
/**
*
* @author emerald000
*/
public class ElderDeepFiend extends CardImpl {
public ElderDeepFiend(UUID ownerId) {
super(ownerId, 5, "Elder Deep-Fiend", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{8}");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Octopus");
this.power = new MageInt(5);
this.toughness = new MageInt(6);
// Flash
this.addAbility(FlashAbility.getInstance());
// Emerge {5}{U}{U}
this.addAbility(new EmergeAbility(this, new ManaCostsImpl<>("{5}{U}{U}")));
// When you cast Elder Deep-Fiend, tap up to four target permanents.
Ability ability = new CastSourceTriggeredAbility(new TapTargetEffect());
ability.addTarget(new TargetPermanent(0, 4, new FilterPermanent("permanent"), false));
this.addAbility(ability);
}
public ElderDeepFiend(final ElderDeepFiend card) {
super(card);
}
@Override
public ElderDeepFiend copy() {
return new ElderDeepFiend(this);
}
}

View file

@ -57,7 +57,7 @@ import mage.filter.predicate.permanent.ControllerPredicate;
public class FinalIteration extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wizards");
private static final FilterSpell filterSpell = new FilterSpell("instant or sorcery spell");
private static final FilterSpell filterSpell = new FilterSpell("an instant or sorcery spell");
static {
filter.add(new SubtypePredicate("Wizard"));
@ -82,7 +82,7 @@ public class FinalIteration extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Wizards you control get +2/+1 and have flying.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(2, 1, Duration.WhileOnBattlefield, filter, true));
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(2, 1, Duration.WhileOnBattlefield, filter, false));
Effect effect = new GainAbilityAllEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter, false);
effect.setText("and have flying");
ability.addEffect(effect);

View file

@ -93,7 +93,7 @@ class FortunesFavorEffect extends OneShotEffect {
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && targetOpponent != null && sourceObject != null) {
Cards cards = new CardsImpl();
cards.addAll(controller.getLibrary().getTopCards(game, 1));
cards.addAll(controller.getLibrary().getTopCards(game, 4));
TargetCard target = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, new FilterCard("cards for the face-down pile"));
targetOpponent.choose(outcome, cards, target, game);
@ -101,7 +101,7 @@ class FortunesFavorEffect extends OneShotEffect {
faceDownPile.addAll(target.getTargets());
cards.removeAll(target.getTargets());
controller.revealCards(sourceObject.getIdName() + " - cards in face-up pile", cards, game);
game.informPlayers(targetOpponent.getLogName() + " puts " + faceDownPile.size() + "card(s) into the face-down pile");
game.informPlayers(targetOpponent.getLogName() + " puts " + faceDownPile.size() + " card(s) into the face-down pile");
MessageToClient message = new MessageToClient("Put the face-down pile into your hand?", "(If you say yes, the face-up pile goes to the graveyard.)");
if (controller.chooseUse(outcome, message, source, game)) {
controller.moveCards(faceDownPile, Zone.HAND, source, game);

View file

@ -29,15 +29,17 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.condition.common.MeldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.MeldEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.constants.TargetController;
/**
*
@ -56,12 +58,19 @@ public class GiselaTheBrokenBlade extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// At the beginning of your end step, if you both own and control Gisela, the Broken Blade and a creature named Bruna, the Fading Light, exile them, then meld them into Brisela, Voice of Nightmares.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Meld ability not implemeted yet.")));
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfEndStepTriggeredAbility(new MeldEffect("Bruna, the Fading Light", new BriselaVoiceOfNightmares(ownerId)), TargetController.YOU, false),
new MeldCondition("Bruna, the Fading Light"),
"At the beginning of your end step, if you both own and control {this} and a creature named Bruna, the Fading Light, exile them, "
+ "then meld them into Brisela, Voice of Nightmares."));
}
public GiselaTheBrokenBlade(final GiselaTheBrokenBlade card) {

View file

@ -29,16 +29,18 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.condition.common.MeldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.MeldEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.constants.TargetController;
/**
*
* @author LevelX2
* @author emerald000
*/
public class GrafRats extends CardImpl {
@ -50,7 +52,11 @@ public class GrafRats extends CardImpl {
this.toughness = new MageInt(1);
// At the beginning of combat on your turn, if you both own and control Graf Rats and a creature named Midnight Scavengers, exile them, then meld them into Chittering Host.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Meld ability not implemeted yet.")));
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfCombatTriggeredAbility(new MeldEffect("Midnight Scavengers", new ChitteringHost(ownerId)), TargetController.YOU, false),
new MeldCondition("Midnight Scavengers"),
"At the beginning of combat on your turn, if you both own and control {this} and a creature named Midnight Scavengers, exile them, then meld them into Chittering Host."));
}
public GrafRats(final GrafRats card) {

View file

@ -30,10 +30,11 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MeldCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.common.MeldEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.mana.ColorlessManaAbility;
@ -63,7 +64,11 @@ public class HanweirBattlements extends CardImpl {
this.addAbility(ability);
// {3}{R}{R},{T}: If you both own and control Hanweir Battlements and a creature named Hanweir Garrison, exile them, then meld them into Hanweir, the Writhing Township.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Meld ability not implemeted yet.")));
ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new MeldEffect("Hanweir Garrison", new HanweirTheWrithingTownship(ownerId)),
new ManaCostsImpl("{3}{R}{R}"), new MeldCondition("Hanweir Garrison"),
"{3}{R}{R}, {T}: If you both own and control {this} and a creature named Hanweir Garrison, exile them, then meld them into Hanweir, the Writhing Township.");
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
public HanweirBattlements(final HanweirBattlements card) {

View file

@ -33,7 +33,7 @@ import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Rarity;
@ -41,7 +41,7 @@ import mage.constants.Rarity;
*
* @author LevelX2
*/
public class HanweirTheWrithingTownship extends CardImpl {
public class HanweirTheWrithingTownship extends MeldCard {
public HanweirTheWrithingTownship(UUID ownerId) {
super(ownerId, 130, "Hanweir, the Writhing Township", Rarity.RARE, new CardType[]{CardType.CREATURE}, "");
@ -56,8 +56,10 @@ public class HanweirTheWrithingTownship extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// Whenever Hanweir, the Writhing Township attacks, put two 3/2 colorless Eldrazi Horror creature tokens onto the battlefield tapped and attacking.
this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new EldraziHorrorToken(), 2, true, true), false));
}

View file

@ -127,7 +127,8 @@ class IdentityThiefEffect extends OneShotEffect {
public IdentityThiefEffect() {
super(Outcome.Detriment);
staticText = "you may exile another target nontoken creature. If you do, {this} becomes a copy of that creature until end of turn. Return that card to the battlefield under its owner's control at the beginning of the next end step";
staticText = "you may exile another target nontoken creature. If you do, {this} becomes a copy of that creature until end of turn. "
+ "Return the exiled card to the battlefield under its owner's control at the beginning of the next end step";
}
public IdentityThiefEffect(final IdentityThiefEffect effect) {

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -46,7 +47,7 @@ import mage.target.common.TargetCardInYourGraveyard;
*/
public class IroncladSlayer extends CardImpl {
private final static FilterCard filter = new FilterCard("Aura or Equipment card");
private final static FilterCard filter = new FilterCard("Aura or Equipment card from your graveyard");
static {
filter.add(Predicates.or(new SubtypePredicate("Aura"), new SubtypePredicate("Equipment")));
@ -61,7 +62,9 @@ public class IroncladSlayer extends CardImpl {
this.toughness = new MageInt(2);
// When Ironclad Slayer enters the battlefield, you may return target Aura or Equipment card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true);
Effect effect = new ReturnToHandTargetEffect();
effect.setText("you may return target Aura or Equipment card from your graveyard to your hand");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, true);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}

View file

@ -53,7 +53,7 @@ public class KessigProwler extends CardImpl {
this.toughness = new MageInt(1);
this.canTransform = true;
this.secondSideCard = new SinousPredator(ownerId);
this.secondSideCard = new SinuousPredator(ownerId);
// {4}{G}: Transform Kessig Prowler.
this.addAbility(new TransformAbility());

View file

@ -30,9 +30,11 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.IntCompareCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.LifelinkAbility;
@ -40,9 +42,8 @@ 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.game.Game;
import mage.game.events.GameEvent;
import mage.watchers.common.PlayerGainedLifeWatcher;
/**
@ -51,6 +52,8 @@ import mage.watchers.common.PlayerGainedLifeWatcher;
*/
public class LoneRider extends CardImpl {
private static final String ruleText = "At the beginning of the end step, if you gained 3 or more life this turn, transform {this}";
public LoneRider(UUID ownerId) {
super(ownerId, 33, "Lone Rider", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.expansionSetCode = "EMN";
@ -70,8 +73,8 @@ public class LoneRider extends CardImpl {
// At the beginning of the end step, if you gained 3 or more life this turn, transform Lone Rider.
this.addAbility(new TransformAbility());
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), TargetController.ANY,
new YouGainedLifeCondition(Condition.ComparisonType.GreaterThan, 2), false), new PlayerGainedLifeWatcher());
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new TransformSourceEffect(true));
this.addAbility(new ConditionalTriggeredAbility(triggered, new YouGainedLifeCondition(Condition.ComparisonType.GreaterThan, 2), ruleText), new PlayerGainedLifeWatcher());
}
public LoneRider(final LoneRider card) {

View file

@ -36,6 +36,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
@ -93,7 +94,7 @@ class LongRoadHomeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
if (permanent.moveToExile(source.getSourceId(), "Otherworldly Journey", source.getSourceId(), game)) {
if (permanent.moveToExile(source.getSourceId(), "Long Road Home", source.getSourceId(), game)) {
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
// only if permanent is in exile (tokens would be stop to exist)
if (exile != null && !exile.isEmpty()) {
@ -147,7 +148,14 @@ class LongRoadHomeReturnFromExileEffect extends OneShotEffect {
if (card != null && objectToReturn.refersTo(card, game)) {
Player owner = game.getPlayer(card.getOwnerId());
if (owner != null) {
game.addEffect(new LongRoadHomeEntersBattlefieldEffect(objectToReturn), source);
if (card instanceof MeldCard) {
MeldCard meldCard = (MeldCard) card;
game.addEffect(new LongRoadHomeEntersBattlefieldEffect(new MageObjectReference(meldCard.getTopHalfCard(), game)), source);
game.addEffect(new LongRoadHomeEntersBattlefieldEffect(new MageObjectReference(meldCard.getBottomHalfCard(), game)), source);
}
else {
game.addEffect(new LongRoadHomeEntersBattlefieldEffect(objectToReturn), source);
}
owner.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
}
}

View file

@ -126,7 +126,7 @@ class MirrorwingDragonCopyTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "Whenever a player casts an instant or sorcery spell that targets only {this}, "
+ "that player copies that spell for each creature he or she controls that the spell could target. "
+ "that player copies that spell for each other creature he or she controls that the spell could target. "
+ "Each copy targets a different one of those creatures.";
}
}
@ -135,7 +135,7 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec
public MirrorwingDragonCopySpellEffect() {
this(new FilterControlledCreaturePermanent());
this.staticText = "that player copies that spell for each creature he or she controls that the spell could target. Each copy targets a different one of those creatures.";
this.staticText = "that player copies that spell for each other creature he or she controls that the spell could target. Each copy targets a different one of those creatures.";
}
public MirrorwingDragonCopySpellEffect(MirrorwingDragonCopySpellEffect effect) {

View file

@ -45,13 +45,13 @@ import mage.game.events.GameEvent.EventType;
*/
public class Providence extends CardImpl {
private static String abilityText = "at the beginning of your first upkeep, your life total becomes 26";
private static String abilityText = "at the beginning of the first upkeep, your life total becomes 26";
public Providence(UUID ownerId) {
super(ownerId, 37, "Providence", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{W}{W}");
this.expansionSetCode = "EMN";
// You may reveal this card from your opening hand. If you do, at the beginning of your first upkeep, your life total becomes 26.
// You may reveal this card from your opening hand. If you do, at the beginning of the first upkeep, your life total becomes 26.
Ability ability = new ChancellorAbility(new ProvidenceDelayedTriggeredAbility(), abilityText);
ability.setRuleAtTheTop(true);
this.addAbility(ability);
@ -87,7 +87,7 @@ class ProvidenceDelayedTriggeredAbility extends DelayedTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return game.getActivePlayerId().equals(controllerId);
return true;
}
@Override

View file

@ -33,6 +33,7 @@ import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
@ -43,14 +44,16 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.FilterPlayer;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.other.PlayerPredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
/**
*
@ -58,6 +61,14 @@ import mage.target.common.TargetOpponent;
*/
public class SavageAlliance extends CardImpl {
private static final FilterPlayer filterPlayer = new FilterPlayer("player whose creatures gain trample");
private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature to deal 2 damage to");
private static final FilterPlayer filterOpponent = new FilterPlayer("opponent whose creatures get dealt damage");
static {
filterOpponent.add(new PlayerPredicate(TargetController.OPPONENT));
}
public SavageAlliance(UUID ownerId) {
super(ownerId, 140, "Savage Alliance", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{R}");
this.expansionSetCode = "EMN";
@ -71,18 +82,20 @@ public class SavageAlliance extends CardImpl {
// Creatures target player controls gain trample until end of turn.
this.getSpellAbility().addEffect(new SavageAllianceGainTrampleEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addTarget(new TargetPlayer(1, 1, false, filterPlayer));
// Savage Alliance deals 2 damage to target creature.;
Mode mode = new Mode();
mode.getEffects().add(new DamageTargetEffect(2));
mode.getTargets().add(new TargetCreaturePermanent());
Effect effect = new DamageTargetEffect(2);
effect.setText("{this} deals 2 damage to target creature");
mode.getEffects().add(effect);
mode.getTargets().add(new TargetCreaturePermanent(filterCreature));
this.getSpellAbility().addMode(mode);
// Savage Alliance deals 1 damage to each creature target opponent controls.
mode = new Mode();
mode.getEffects().add(new SavageAllianceDamageEffect());
mode.getTargets().add(new TargetOpponent());
mode.getTargets().add(new TargetPlayer(1, 1, false, filterOpponent));
this.getSpellAbility().addMode(mode);
}

View file

@ -48,7 +48,7 @@ import mage.filter.common.FilterControlledCreaturePermanent;
public class SelflessSpirit extends CardImpl {
public SelflessSpirit(UUID ownerId) {
super(ownerId, 40, "Selfless Soul", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}");
super(ownerId, 40, "Selfless Spirit", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.expansionSetCode = "EMN";
this.subtype.add("Spirit");
this.power = new MageInt(2);

View file

@ -49,7 +49,7 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class SigardianPriest extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Human sources");
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Human creature");
static {
filter.add(Predicates.not(new SubtypePredicate("Human")));

View file

@ -40,10 +40,10 @@ import mage.constants.Zone;
*
* @author fireshoes
*/
public class SinousPredator extends CardImpl {
public class SinuousPredator extends CardImpl {
public SinousPredator(UUID ownerId) {
super(ownerId, 163, "Sinous Predator", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
public SinuousPredator(UUID ownerId) {
super(ownerId, 163, "Sinuous Predator", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Werewolf");
@ -53,16 +53,16 @@ public class SinousPredator extends CardImpl {
// this card is the second face of double-faced card
this.nightCard = true;
// Sinous Predator can't be blocked by more than one creature.
// Sinuous Predator can't be blocked by more than one creature.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByMoreThanOneSourceEffect()));
}
public SinousPredator(final SinousPredator card) {
public SinuousPredator(final SinuousPredator card) {
super(card);
}
@Override
public SinousPredator copy() {
return new SinousPredator(this);
public SinuousPredator copy() {
return new SinuousPredator(this);
}
}

View file

@ -28,6 +28,7 @@
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
@ -46,7 +47,9 @@ public class SpectralReserves extends CardImpl {
this.expansionSetCode = "EMN";
// Put two 1/1 white Spirit creature tokens with flying onto the battlefield. You gain 2 life.
this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritWhiteToken("EMN"), 2));
Effect effect = new CreateTokenEffect(new SpiritWhiteToken("EMN"), 2);
effect.setText("Put two 1/1 white Spirit creature tokens with flying onto the battlefield");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new GainLifeEffect(2));
}

View file

@ -43,7 +43,6 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@ -69,7 +68,7 @@ public class SpontaneousMutation extends CardImpl {
this.addAbility(ability);
// Enchanted creature gets -X/-0, where X is the number of cards in your graveyard.
DynamicValue value = new SignInversionDynamicValue(new CardsInControllerGraveyardCount(new FilterCreatureCard()));
DynamicValue value = new SignInversionDynamicValue(new CardsInControllerGraveyardCount());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(value, new StaticValue(-0))));
}

View file

@ -45,7 +45,7 @@ import mage.filter.predicate.permanent.ControllerPredicate;
*/
public class SubjugatorAngel extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents controller");
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));

View file

@ -42,9 +42,8 @@ import mage.constants.Rarity;
public class SuccumbToTemptation extends CardImpl {
public SuccumbToTemptation(UUID ownerId) {
super(ownerId, 107, "Succumb to Temptation", Rarity.COMMON, new CardType[]{}, "{1}{B}{B}");
super(ownerId, 107, "Succumb to Temptation", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{B}{B}");
this.expansionSetCode = "EMN";
this.supertype.add("Insant");
// You draw two cards and you lose 2 life.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));

View file

@ -30,6 +30,7 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
@ -63,7 +64,9 @@ public class ThaliasLancers extends CardImpl {
this.addAbility(FirstStrikeAbility.getInstance());
// When Thalia's Lancers enters the battlefield, you may search your library for a legendary card, reveal it, put it into your hand, then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true, true), true));
Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true, true);
effect.setText("you may search your library for a legendary card, reveal it, put it into your hand, then shuffle your library");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect, true));
}
public ThaliasLancers(final ThaliasLancers card) {

View file

@ -39,7 +39,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.permanent.token.SoldierToken;
import mage.game.permanent.token.Token;
/**
*
@ -56,7 +56,7 @@ public class ThrabenStandardBearer extends CardImpl {
this.toughness = new MageInt(1);
// {1}{W}, {T}, Discard a card: Put a 1/1 white Human Soldier creature token onto the battlefield.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SoldierToken()), new ManaCostsImpl<>("{1}{W}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new HumanSoldierToken()), new ManaCostsImpl<>("{1}{W}"));
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardCardCost());
this.addAbility(ability);
@ -71,3 +71,16 @@ public class ThrabenStandardBearer extends CardImpl {
return new ThrabenStandardBearer(this);
}
}
class HumanSoldierToken extends Token {
public HumanSoldierToken() {
super("Human Soldier", "1/1 white Human Soldier creature token");
cardType.add(CardType.CREATURE);
subtype.add("Human");
subtype.add("Soldier");
color.setWhite(true);
power = new MageInt(1);
toughness = new MageInt(1);
}
}

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.keyword.EmergeAbility;
@ -47,7 +48,7 @@ import mage.target.common.TargetCardInYourGraveyard;
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class VexingScuttler extends CardImpl {
private static final FilterCard filter = new FilterCard("instant or sorcery card from your graveyard");
static {
@ -66,8 +67,11 @@ public class VexingScuttler extends CardImpl {
// Emerge {6}{U}
this.addAbility(new EmergeAbility(this, new ManaCostsImpl<>("{6}{U}")));
// When you cast Vexing Scuttler, you may return target instant or sorcery card from your graveyard to your hand.
Ability ability = new CastSourceTriggeredAbility(new ReturnToHandTargetEffect(), true);
Effect effect = new ReturnToHandTargetEffect();
effect.setText("you may return target instant or sorcery card from your graveyard to your hand");
Ability ability = new CastSourceTriggeredAbility(effect, true);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}

View file

@ -0,0 +1,52 @@
/*
* 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.fridaynightmagic;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class FlayingTendrils extends mage.sets.oathofthegatewatch.FlayingTendrils {
public FlayingTendrils(UUID ownerId) {
super(ownerId);
this.cardNumber = 196;
this.expansionSetCode = "FNMP";
}
public FlayingTendrils(final FlayingTendrils card) {
super(card);
}
@Override
public FlayingTendrils copy() {
return new FlayingTendrils(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.gameday;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class HeronsGraceChampion extends mage.sets.eldritchmoon.HeronsGraceChampion {
public HeronsGraceChampion(UUID ownerId) {
super(ownerId);
this.cardNumber = 54;
this.expansionSetCode = "MGDC";
}
public HeronsGraceChampion(final HeronsGraceChampion card) {
super(card);
}
@Override
public HeronsGraceChampion copy() {
return new HeronsGraceChampion(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.gameday;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class IncorrigibleYouths extends mage.sets.shadowsoverinnistrad.IncorrigibleYouths {
public IncorrigibleYouths(UUID ownerId) {
super(ownerId);
this.cardNumber = 51;
this.expansionSetCode = "MGDC";
}
public IncorrigibleYouths(final IncorrigibleYouths card) {
super(card);
}
@Override
public IncorrigibleYouths copy() {
return new IncorrigibleYouths(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.gameday;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Unsubstantiate extends mage.sets.eldritchmoon.Unsubstantiate {
public Unsubstantiate(UUID ownerId) {
super(ownerId);
this.cardNumber = 53;
this.expansionSetCode = "MGDC";
}
public Unsubstantiate(final Unsubstantiate card) {
super(card);
}
@Override
public Unsubstantiate copy() {
return new Unsubstantiate(this);
}
}

View file

@ -28,9 +28,6 @@
package mage.sets.magic2012;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -40,6 +37,8 @@ import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
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.Predicates;
@ -52,7 +51,7 @@ import mage.game.events.GameEvent;
*/
public class CallToTheGrave extends CardImpl {
private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice Call to the Grave.";
private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice {this}.";
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a non-Zombie creature");
static {

View file

@ -0,0 +1,52 @@
/*
* 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.mediainserts;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class AssembledAlphas extends mage.sets.eldritchmoon.AssembledAlphas {
public AssembledAlphas(UUID ownerId) {
super(ownerId);
this.cardNumber = 160;
this.expansionSetCode = "MBP";
}
public AssembledAlphas(final AssembledAlphas card) {
super(card);
}
@Override
public AssembledAlphas copy() {
return new AssembledAlphas(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mediainserts;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class NiblisOfFrost extends mage.sets.eldritchmoon.NiblisOfFrost {
public NiblisOfFrost(UUID ownerId) {
super(ownerId);
this.cardNumber = 158;
this.expansionSetCode = "MBP";
}
public NiblisOfFrost(final NiblisOfFrost card) {
super(card);
}
@Override
public NiblisOfFrost copy() {
return new NiblisOfFrost(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mediainserts;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class NoosegrafMob extends mage.sets.eldritchmoon.NoosegrafMob {
public NoosegrafMob(UUID ownerId) {
super(ownerId);
this.cardNumber = 159;
this.expansionSetCode = "MBP";
}
public NoosegrafMob(final NoosegrafMob card) {
super(card);
}
@Override
public NoosegrafMob copy() {
return new NoosegrafMob(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mediainserts;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class SanctifierOfSouls extends mage.sets.eldritchmoon.SanctifierOfSouls {
public SanctifierOfSouls(UUID ownerId) {
super(ownerId);
this.cardNumber = 157;
this.expansionSetCode = "MBP";
}
public SanctifierOfSouls(final SanctifierOfSouls card) {
super(card);
}
@Override
public SanctifierOfSouls copy() {
return new SanctifierOfSouls(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mediainserts;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class UlvenwaldObserver extends mage.sets.eldritchmoon.UlvenwaldObserver {
public UlvenwaldObserver(UUID ownerId) {
super(ownerId);
this.cardNumber = 161;
this.expansionSetCode = "MBP";
}
public UlvenwaldObserver(final UlvenwaldObserver card) {
super(card);
}
@Override
public UlvenwaldObserver copy() {
return new UlvenwaldObserver(this);
}
}

View file

@ -0,0 +1,119 @@
/*
* 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.mirrodin;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author CountAndromalius
*/
public class SerumTank extends CardImpl {
public SerumTank(UUID ownerId) {
super(ownerId, 240, "Serum Tank", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}");
this.expansionSetCode = "MRD";
// Whenever {this} or another artifact comes into play, put a charge counter on {this}.
Effect effect = new AddCountersSourceEffect(CounterType.CHARGE.createInstance());
effect.setText("put a charge counter on {this}");
this.addAbility(new SerumTankTriggeredAbility(effect));
// {3}, {tap}, Remove a charge counter from {this}: Draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{3}"));
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
public SerumTank(final SerumTank card) {
super(card);
}
@java.lang.Override
public SerumTank copy() {
return new SerumTank(this);
}
}
class SerumTankTriggeredAbility extends TriggeredAbilityImpl {
SerumTankTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
}
SerumTankTriggeredAbility(final SerumTankTriggeredAbility ability) {
super(ability);
}
@java.lang.Override
public SerumTankTriggeredAbility copy() {
return new SerumTankTriggeredAbility(this);
}
@java.lang.Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@java.lang.Override
public boolean checkTrigger(GameEvent event, Game game) {
UUID targetId = event.getTargetId();
Permanent permanent = game.getPermanent(targetId);
if (permanent.getCardType().contains(CardType.ARTIFACT)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(permanent, game));
}
return true;
}
return false;
}
@java.lang.Override
public String getRule() {
return "Whenever {this} or another artifact enters the battlefield, put a charge counter on {this}.";
}
}

View file

@ -0,0 +1,137 @@
/*
* 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.odyssey;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.VariableCostImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Dilnu
*/
public class LiquidFire extends CardImpl {
public LiquidFire(UUID ownerId) {
super(ownerId, 201, "Liquid Fire", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
this.expansionSetCode = "ODY";
// As an additional cost to cast Liquid Fire, choose a number between 0 and 5.
this.getSpellAbility().addCost(new LiquidFireCost());
// Liquid Fire deals X damage to target creature and 5 minus X damage to that creature's controller, where X is the chosen number.
DynamicValue choiceValue = new GetXValue();
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new LiquidFireEffect(choiceValue));
}
public LiquidFire(final LiquidFire card) {
super(card);
}
@Override
public LiquidFire copy() {
return new LiquidFire(this);
}
private static class LiquidFireEffect extends OneShotEffect {
protected DynamicValue choiceValue;
public LiquidFireEffect(DynamicValue choiceValue) {
super(Outcome.Damage);
this.staticText = "{this} deals X damage to target creature and 5 minus X damage to that creature's controller, where X is the chosen number.";
this.choiceValue = choiceValue;
}
public LiquidFireEffect(LiquidFireEffect effect) {
super(effect);
this.choiceValue = effect.choiceValue;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
int creatureDamage = choiceValue.calculate(game, source, this);
int playerDamage = 5 - creatureDamage;
if (target != null) {
target.damage(creatureDamage, source.getSourceId(), game, false, true);
Player controller = game.getPlayer(target.getControllerId());
if (controller != null) {
controller.damage(playerDamage, source.getSourceId(), game, false, true);
}
return true;
}
return false;
}
@Override
public Effect copy() {
return new LiquidFireEffect(this);
}
}
class LiquidFireCost extends VariableCostImpl {
public LiquidFireCost() {
super("Choose a Number");
this.text = "As an additional cost to cast {source}, choose a number between 0 and 5";
}
public LiquidFireCost(final LiquidFireCost cost) {
super(cost);
}
@Override
public Cost copy() {
return new LiquidFireCost(this);
}
@Override
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
return null;
}
@Override
public int getMaxValue(Ability source, Game game) {
return 5;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.planechase;
import java.util.UUID;
/**
*
* @author CountAndromalius
*/
public class SerumTank extends mage.sets.mirrodin.SerumTank {
public SerumTank (UUID ownerId) {
super(ownerId);
this.cardNumber = 125;
this.expansionSetCode = "HOP";
}
public SerumTank (final SerumTank card) {
super(card);
}
@Override
public SerumTank copy() {
return new SerumTank(this);
}
}

View file

@ -0,0 +1,111 @@
/*
* 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.ravnica;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PreventDamageByTargetEffect;
import mage.abilities.effects.common.UntapAllControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Dilnu
*/
public class BorosFuryShield extends CardImpl {
private static final FilterAttackingOrBlockingCreature filter = new FilterAttackingOrBlockingCreature();
public BorosFuryShield(UUID ownerId) {
super(ownerId, 5, "Boros Fury-Shield", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "RAV";
// Prevent all combat damage that would be dealt by target attacking or blocking creature this turn.
this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
// If {R} was spent to cast Boros Fury-Shield, it deals damage to that creature's controller equal to the creature's power.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new BorosFuryShieldDamageEffect(),
new ManaWasSpentCondition(ColoredManaSymbol.R), "If {R} was spent to cast {this}, it deals damage to that creature's controller equal to the creature's power"));
}
public BorosFuryShield(final BorosFuryShield card) {
super(card);
}
@Override
public BorosFuryShield copy() {
return new BorosFuryShield(this);
}
class BorosFuryShieldDamageEffect extends OneShotEffect {
BorosFuryShieldDamageEffect() {
super(Outcome.Damage);
staticText = "{this} deals damage to that creature's controller equal to the creature's power";
}
BorosFuryShieldDamageEffect(final BorosFuryShieldDamageEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
if (target != null) {
Player player = game.getPlayer(target.getControllerId());
if (player != null) {
int power = target.getPower().getValue();
player.damage(power, source.getId(), game, false, true);
}
}
return false;
}
@Override
public Effect copy() {
return new BorosFuryShieldDamageEffect(this);
}
}
}

View file

@ -0,0 +1,120 @@
/*
* 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.ravnica;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Dilnu
*/
public class Brightflame extends CardImpl {
public Brightflame(UUID ownerId) {
super(ownerId, 194, "Brightflame", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{R}{R}{W}{W}");
this.expansionSetCode = "RAV";
// Radiance - Brightflame deals X damage to target creature and each other creature that shares a color with it. You gain life equal to the damage dealt this way.
this.getSpellAbility().addEffect(new BrightflameEffect(new ManacostVariableValue()));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().setAbilityWord(AbilityWord.RADIANCE);
}
public Brightflame(final Brightflame card) {
super(card);
}
@Override
public Brightflame copy() {
return new Brightflame(this);
}
}
class BrightflameEffect extends OneShotEffect {
static final FilterPermanent filter = new FilterPermanent("creature");
protected DynamicValue amount;
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
BrightflameEffect(DynamicValue amount) {
super(Outcome.Damage);
this.amount = amount;
staticText = "{this} deals X damage to target creature and each other creature that shares a color with it. You gain life equal to the damage dealt this way.";
}
BrightflameEffect(final BrightflameEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
int damageDealt = 0;
if (target != null) {
ObjectColor color = target.getColor(game);
damageDealt += target.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, true);
for (Permanent p : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
if (!target.getId().equals(p.getId()) && p.getColor(game).shares(color)) {
damageDealt += p.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, true);
}
}
Player you = game.getPlayer(source.getControllerId());
if (you != null && damageDealt > 0) {
you.gainLife(damageDealt, game);
}
return true;
}
return false;
}
@Override
public BrightflameEffect copy() {
return new BrightflameEffect(this);
}
}

View file

@ -0,0 +1,103 @@
/*
* 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.ravnica;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
* @author Dilnu
*/
public class LightOfSanction extends CardImpl {
public LightOfSanction(UUID ownerId) {
super(ownerId, 24, "Light of Sanction", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}");
this.expansionSetCode = "RAV";
// Prevent all damage that would be dealt to creatures you control by sources you control.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LightOfSanctionEffect()));
}
public LightOfSanction(final LightOfSanction card) {
super(card);
}
@Override
public LightOfSanction copy() {
return new LightOfSanction(this);
}
}
class LightOfSanctionEffect extends PreventionEffectImpl {
public LightOfSanctionEffect() {
super(Duration.EndOfGame);
this.staticText = "Prevent all damage that would be dealt to creatures you control by sources you control.";
consumable = false;
}
public LightOfSanctionEffect(LightOfSanctionEffect effect) {
super(effect);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType().equals(GameEvent.EventType.DAMAGE_CREATURE)) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) {
MageObject damageSource = game.getObject(event.getSourceId());
if (damageSource instanceof Controllable) {
return ((Controllable) damageSource).getControllerId().equals(source.getControllerId());
}
else if (damageSource instanceof Card) {
return ((Card) damageSource).getOwnerId().equals(source.getControllerId());
}
}
}
return false;
}
@Override
public LightOfSanctionEffect copy() {
return new LightOfSanctionEffect(this);
}
}

View file

@ -30,17 +30,23 @@ package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.MeldCard;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
@ -60,7 +66,7 @@ public class EssenceFlux extends CardImpl {
Effect effect = new ExileTargetForSourceEffect();
effect.setApplyEffectsAfter();
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new EssenceFluxEffect(false, true));
this.getSpellAbility().addEffect(new EssenceFluxEffect());
}
public EssenceFlux(final EssenceFlux card) {
@ -73,14 +79,14 @@ public class EssenceFlux extends CardImpl {
}
}
class EssenceFluxEffect extends ReturnToBattlefieldUnderOwnerControlTargetEffect {
class EssenceFluxEffect extends OneShotEffect {
public EssenceFluxEffect(boolean tapped, boolean fromExileZone) {
super(tapped, fromExileZone);
staticText = ", then return that card to the battlefield under its owner's control. If it's a Spirit, put a +1/+1 counter on it";
EssenceFluxEffect() {
super(Outcome.Benefit);
staticText = "return that card to the battlefield under its owner's control";
}
public EssenceFluxEffect(final EssenceFluxEffect effect) {
EssenceFluxEffect(final EssenceFluxEffect effect) {
super(effect);
}
@ -91,22 +97,43 @@ class EssenceFluxEffect extends ReturnToBattlefieldUnderOwnerControlTargetEffect
@Override
public boolean apply(Game game, Ability source) {
Card card = null;
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exilZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
if (exileZone != null && getTargetPointer().getFirst(game, source) != null) {
card = exileZone.get(getTargetPointer().getFirst(game, source), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Cards cardsToBattlefield = new CardsImpl();
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exileZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
if (exileZone != null) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
if (exileZone.contains(targetId)) {
cardsToBattlefield.add(targetId);
}
else {
Card card = game.getCard(targetId);
if (card != null && card instanceof MeldCard) {
MeldCard meldCard = (MeldCard) card;
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter() && exileZone.contains(topCard.getId())) {
cardsToBattlefield.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter() && exileZone.contains(bottomCard.getId())) {
cardsToBattlefield.add(bottomCard);
}
}
}
}
}
}
}
if (super.apply(game, source)) {
if (card != null) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null && permanent.getSubtype().contains("Spirit")) {
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance());
effect.setTargetPointer(new FixedTarget(permanent, game));
return effect.apply(game, source);
if (!cardsToBattlefield.isEmpty()) {
controller.moveCards(cardsToBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
for (UUID cardId : cardsToBattlefield) {
Permanent permanent = game.getPermanent(cardId);
if (permanent != null && permanent.getSubtype().contains("Spirit")) {
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance());
effect.setTargetPointer(new FixedTarget(permanent, game));
return effect.apply(game, source);
}
}
}
return true;

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
@ -66,7 +67,9 @@ public class StitchedMangler extends CardImpl {
// When Stitched Mangler enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step.
EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect());
ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect());
Effect effect = new DontUntapInControllersNextUntapStepTargetEffect();
effect.setText("That creature doesn't untap during its controller's next untap step");
ability.addEffect(effect);
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}

View file

@ -0,0 +1,93 @@
/*
* 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.weatherlight;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.common.RegenerateTargetEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Dilnu
*/
public class DebtOfLoyalty extends CardImpl {
public DebtOfLoyalty(UUID ownerId) {
super(ownerId, 127, "Debt of Loyalty", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{W}{W}");
this.expansionSetCode = "WTH";
// Regenerate target creature. You gain control of that creature if it regenerates this way.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DebtOfLoyaltyEffect());
}
public DebtOfLoyalty(final DebtOfLoyalty card) {
super(card);
}
@Override
public DebtOfLoyalty copy() {
return new DebtOfLoyalty(this);
}
class DebtOfLoyaltyEffect extends RegenerateTargetEffect {
public DebtOfLoyaltyEffect ( ) {
super();
this.staticText = "Regenerate target creature. You gain control of that creature if it regenerates this way.";
}
public DebtOfLoyaltyEffect(final DebtOfLoyaltyEffect effect) {
super(effect);
}
@Override
public DebtOfLoyaltyEffect copy() {
return new DebtOfLoyaltyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (super.apply(game, source) && permanent != null) {
GainControlTargetEffect effect = new GainControlTargetEffect(Duration.EndOfGame);
effect.setTargetPointer(targetPointer);
game.addEffect(effect, source);
return true;
}
return false;
}
}
}

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage-tests</artifactId>

View file

@ -0,0 +1,98 @@
/*
* 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.control;
import org.mage.test.cards.prevention.*;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class DebtOfLoyaltyTest extends CardTestPlayerBase {
@Test
public void testDebtOfLoyaltyEffect_regen() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
// Tremor deals 1 damage to each creature without flying.
addCard(Zone.HAND, playerA, "Tremor"); // Sorcery {R}
// Regenerate target creature. You gain control of that creature if it regenerates this way.
addCard(Zone.HAND, playerA, "Debt of Loyalty"); // Instant {1WW}
addCard(Zone.BATTLEFIELD, playerB, "Metallic Sliver"); // 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Debt of Loyalty", "Metallic Sliver");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tremor");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Tremor", 1);
assertPermanentCount(playerB, "Metallic Sliver", 0);
assertGraveyardCount(playerB, "Metallic Sliver", 0);
assertPermanentCount(playerA, "Metallic Sliver", 1);
Permanent sliver = getPermanent("Metallic Sliver", playerA.getId());
Assert.assertNotNull(sliver);
// regenerate causes to tap
Assert.assertTrue(sliver.isTapped());
}
@Test
public void testDebtOfLoyaltyEffect_noRegen() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
// Tremor deals 1 damage to each creature without flying.
addCard(Zone.HAND, playerA, "Tremor"); // Sorcery {R}
// Regenerate target creature. You gain control of that creature if it regenerates this way.
addCard(Zone.HAND, playerA, "Debt of Loyalty"); // Instant {1WW}
addCard(Zone.BATTLEFIELD, playerB, "Metallic Sliver"); // 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Debt of Loyalty", "Metallic Sliver");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerB, "Metallic Sliver", 1);
Permanent sliver = getPermanent("Metallic Sliver", playerB.getId());
Assert.assertNotNull(sliver);
// No regeneration occured.
Assert.assertFalse(sliver.isTapped());
}
}

View file

@ -0,0 +1,160 @@
/*
* 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.planeswalker;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class TamiyoTest extends CardTestPlayerBase {
/*
* Reported bug: I activated Tamiyo's +1 ability on a 5/5 Gideon and his 2/2 Knight Ally, but when they both attacked
* and dealt damage I only drew one card when I'm pretty sure I was supposed to draw for each of the two.
*/
@Test
public void testFieldResearcherFirstEffectOnGideon() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
/* Gideon, Ally of Zendikar {2}{W}{W} - 4 loyalty
* +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible
* that's still a planeswalker. Prevent all damage that would be dealt to him this turn.
* 0: Put a 2/2 white Knight Ally creature token onto the battlefield.
**/
addCard(Zone.BATTLEFIELD, playerA, "Gideon, Ally of Zendikar", 1);
// put 2/2 knight ally token on battlefield
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+0: Put a");
// next, activate Gideon to make him a 5/5 human soldier ally creature
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Until end of turn");
// finally, use Tamiyo +1 on both creatures
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Knight Ally^Gideon, Ally of Zendikar"); // both token and Gideon as creature
// attack with both unblocked
attack(3, playerA, "Knight Ally");
attack(3, playerA, "Gideon, Ally of Zendikar");
setStopAt(3, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 13); // 5 + 2 damage, 20 - 7 = 13
assertPermanentCount(playerA, "Tamiyo, Field Researcher", 1);
assertPermanentCount(playerA, "Gideon, Ally of Zendikar", 1);
assertPermanentCount(playerA, "Knight Ally", 1);
assertHandCount(playerA, 3); // two cards drawn from each creature dealing damage + 1 card drawn on turn
}
/*
* Testing more basic scenario with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectSimpleCreatureAttacks() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bronze Sable", 1); // 2/1
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Bronze Sable");
attack(1, playerA, "Bronze Sable");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 18);
assertHandCount(playerA, 1);
}
/*
* Testing more basic scenario with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectSimpleCreaturesAttacks() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bronze Sable", 1); // 2/1
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // 2/3
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Bronze Sable^Sylvan Advocate");
attack(1, playerA, "Bronze Sable");
attack(1, playerA, "Sylvan Advocate");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 16);
assertHandCount(playerA, 2);
}
/*
* Testing more basic scenarios with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectAttackAndBlock() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // 2/3
addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Sylvan Advocate");
attack(1, playerA, "Sylvan Advocate");
attack(2, playerB, "Memnite");
block(2, playerA, "Sylvan Advocate", "Memnite");
setStopAt(2, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 18);
assertHandCount(playerA, 2); // Sylvan Advocate dealt combat damage twice
}
}

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 org.mage.test.cards.prevention;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class LightOfSanctionTest extends CardTestPlayerBase {
@Test
public void testLightOfSanctionEffect() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Tremor deals 1 damage to each creature without flying.
addCard(Zone.HAND, playerA, "Tremor"); // Sorcery {R}
// Prevent all damage that would be dealt to creatures you control by sources you control.
addCard(Zone.BATTLEFIELD, playerA, "Light of Sanction");
addCard(Zone.BATTLEFIELD, playerA, "Metallic Sliver"); // 1/1
addCard(Zone.BATTLEFIELD, playerA, "Dross Crocodile"); // 5/1
addCard(Zone.BATTLEFIELD, playerB, "Metallic Sliver"); // 1/1
addCard(Zone.BATTLEFIELD, playerB, "Dross Crocodile"); // 5/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tremor");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Tremor", 1);
assertPermanentCount(playerA, "Metallic Sliver", 1);
assertPermanentCount(playerA, "Dross Crocodile", 1);
assertGraveyardCount(playerB, "Metallic Sliver", 1);
assertGraveyardCount(playerB, "Dross Crocodile", 1);
}
}

View file

@ -5,7 +5,7 @@
<parent>
<artifactId>mage-root</artifactId>
<groupId>org.mage</groupId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.12</version>
<version>1.4.13</version>
</parent>
<artifactId>mage</artifactId>

View file

@ -493,7 +493,10 @@ public abstract class AbilityImpl implements Ability {
for (VariableCost variableCost : this.costs.getVariableCosts()) {
if (!(variableCost instanceof VariableManaCost)) {
int xValue = variableCost.announceXValue(this, game);
costs.add(variableCost.getFixedCostsFromAnnouncedValue(xValue));
Cost fixedCost = variableCost.getFixedCostsFromAnnouncedValue(xValue);
if (fixedCost != null) {
costs.add(fixedCost);
}
// set the xcosts to paid
variableCost.setAmount(xValue);
((Cost) variableCost).setPaid();

View file

@ -69,10 +69,10 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
@Override
public void trigger(Game game, UUID controllerId) {
//20091005 - 603.4
if (!(this instanceof DelayedTriggeredAbility)) {
setSourceObject(null, game);
}
if (checkInterveningIfClause(game)) {
if (!(this instanceof DelayedTriggeredAbility)) {
setSourceObject(null, game);
}
game.addTriggeredAbility(this);
}
}

View file

@ -48,21 +48,22 @@ public class SacrificeAllTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
boolean sacrificed = false;
switch (sacrificingPlayer) {
case YOU:
if (event.getPlayerId().equals(getControllerId())) {
return false;
sacrificed = true;
}
break;
case OPPONENT:
Player controller = game.getPlayer(getControllerId());
if (controller == null || !controller.hasOpponent(event.getPlayerId(), game)) {
return false;
sacrificed = true;
}
break;
}
Permanent sacrificedPermanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
return sacrificedPermanent != null && filter.match(sacrificedPermanent, getSourceId(), getControllerId(), game);
return sacrificed && sacrificedPermanent != null && filter.match(sacrificedPermanent, getSourceId(), getControllerId(), game);
}
@Override

View file

@ -0,0 +1,69 @@
/*
* 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.abilities.condition.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author emerald000
*/
public class MeldCondition implements Condition {
private final String meldWithName;
public MeldCondition(String meldWithName) {
this.meldWithName = meldWithName;
}
@Override
public boolean apply(Game game, Ability source) {
MageObject sourceMageObject = source.getSourceObjectIfItStillExists(game);
if (sourceMageObject != null && sourceMageObject instanceof Permanent) {
Permanent sourcePermanent = (Permanent) sourceMageObject;
if (sourcePermanent.getControllerId().equals(source.getControllerId())
&& sourcePermanent.getOwnerId().equals(source.getControllerId())) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
filter.add(new NamePredicate(this.meldWithName));
for (Permanent meldWithPermanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (meldWithPermanent.getOwnerId().equals(source.getControllerId())) {
return true;
}
}
}
}
return false;
}
}

View file

@ -159,7 +159,10 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
return staticText;
}
if (targetName != null && targetName.length() > 0) {
return targetName + " doesn't untap during its controller's next untap step";
if (targetName.equals("Those creatures")) {
return targetName + " don't untap during their controller's next untap step";
} else
return targetName + " doesn't untap during its controller's next untap step";
} else {
return "target " + (mode == null ? "creature" : mode.getTargets().get(0).getTargetName()) + " doesn't untap during its controller's next untap step";
}

View file

@ -0,0 +1,111 @@
/*
* 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.abilities.effects.common;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.MeldCard;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author emerald000
*/
public class MeldEffect extends OneShotEffect {
private final String meldWithName;
private final MeldCard meldCard;
public MeldEffect(String meldWithName, MeldCard meldCard) {
super(Outcome.Benefit);
this.meldWithName = meldWithName;
this.meldCard = meldCard;
}
public MeldEffect(final MeldEffect effect) {
super(effect);
this.meldWithName = effect.meldWithName;
this.meldCard = effect.meldCard;
}
@Override
public MeldEffect copy() {
return new MeldEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
// Find the two permanents to meld.
UUID sourceId = source.getSourceId();
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature named " + meldWithName);
filter.add(new NamePredicate(meldWithName));
TargetPermanent target = new TargetControlledCreaturePermanent(filter);
Set<UUID> meldWithList = target.possibleTargets(sourceId, source.getControllerId(), game);
UUID meldWithId;
if (meldWithList.size() == 1) {
meldWithId = meldWithList.iterator().next();
}
else {
controller.choose(Outcome.BoostCreature, target, sourceId, game);
meldWithId = target.getFirstTarget();
}
// Exile the two permanents to meld.
Permanent sourcePermanent = game.getPermanent(sourceId);
Permanent meldWithPermanent = game.getPermanent(meldWithId);
sourcePermanent.moveToExile(null, "", sourceId, game);
meldWithPermanent.moveToExile(null, "", sourceId, game);
// Create the meld card and move it to the battlefield.
Card sourceCard = game.getExile().getCard(sourceId, game);
Card meldWithCard = game.getExile().getCard(meldWithId, game);
if (!sourceCard.isCopy() && !meldWithCard.isCopy()) {
meldCard.setOwnerId(controller.getId());
meldCard.setTopHalfCard(meldWithCard, game);
meldCard.setbottomHalfCard(sourceCard, game);
meldCard.setMelded(true);
game.addMeldCard(meldCard.getId(), meldCard);
game.getState().addCard(meldCard);
meldCard.moveToZone(Zone.BATTLEFIELD, sourceId, game, false);
}
return true;
}
return false;
}
}

View file

@ -33,6 +33,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.MeldCard;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.ExileZone;
@ -79,33 +80,40 @@ public class ReturnToBattlefieldUnderOwnerControlTargetEffect extends OneShotEff
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Cards cardsToMove = new CardsImpl();
Cards cardsToBattlefield = new CardsImpl();
if (fromExileZone) {
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exilZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exileZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
if (exileZone != null) {
for (UUID cardId : getTargetPointer().getTargets(game, source)) {
Card card = exileZone.get(cardId, game);
if (card != null) {
cardsToMove.add(card);
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
if (exileZone.contains(targetId)) {
cardsToBattlefield.add(targetId);
}
else {
Card card = game.getCard(targetId);
if (card != null && card instanceof MeldCard) {
MeldCard meldCard = (MeldCard) card;
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter() && exileZone.contains(topCard.getId())) {
cardsToBattlefield.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter() && exileZone.contains(bottomCard.getId())) {
cardsToBattlefield.add(bottomCard);
}
}
}
}
}
}
} else {
for (UUID cardId : getTargetPointer().getTargets(game, source)) {
Card card = game.getCard(cardId);
if (card != null) {
cardsToMove.add(card);
}
}
cardsToBattlefield.addAll(getTargetPointer().getTargets(game, source));
}
if (!cardsToMove.isEmpty()) {
controller.moveCards(cardsToMove.getCards(game),
Zone.BATTLEFIELD, source, game, tapped, false, true, null);
return true;
if (!cardsToBattlefield.isEmpty()) {
controller.moveCards(cardsToBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, tapped, false, true, null);
}
return true;
}
return false;
}

View file

@ -33,6 +33,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.MeldCard;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.ExileZone;
@ -79,13 +80,27 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe
if (controller != null) {
Cards cardsToBattlefield = new CardsImpl();
if (fromExileZone) {
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exilZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exileZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
if (exileZone != null) {
for (Card card : exileZone.getCards(game)) {
if (getTargetPointer().getTargets(game, source).contains(card.getId())) {
cardsToBattlefield.add(card);
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
if (exileZone.contains(targetId)) {
cardsToBattlefield.add(targetId);
}
else {
Card card = game.getCard(targetId);
if (card != null && card instanceof MeldCard) {
MeldCard meldCard = (MeldCard) card;
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter() && exileZone.contains(topCard.getId())) {
cardsToBattlefield.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter() && exileZone.contains(bottomCard.getId())) {
cardsToBattlefield.add(bottomCard);
}
}
}
}
}

View file

@ -0,0 +1,360 @@
/*
* 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.cards;
import java.util.ArrayList;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import static mage.constants.Zone.EXILED;
import static mage.constants.Zone.GRAVEYARD;
import static mage.constants.Zone.HAND;
import static mage.constants.Zone.LIBRARY;
import mage.counters.Counter;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.PermanentMeld;
import mage.players.Player;
/**
*
* @author emerald000
*/
public abstract class MeldCard extends CardImpl {
protected Card topHalfCard;
protected Card bottomHalfCard;
protected int topLastZoneChangeCounter;
protected int bottomLastZoneChangeCounter;
protected boolean isMelded;
public MeldCard(UUID ownerId, int cardNumber, String name, Rarity rarity, CardType[] cardTypes, String costs) {
super(ownerId, cardNumber, name, rarity, cardTypes, costs);
}
public MeldCard(MeldCard card) {
super(card);
this.topHalfCard = card.topHalfCard;
this.bottomHalfCard = card.bottomHalfCard;
this.topLastZoneChangeCounter = card.topLastZoneChangeCounter;
this.bottomLastZoneChangeCounter = card.bottomLastZoneChangeCounter;
this.isMelded = card.isMelded;
}
public void setMelded(boolean isMelded) {
this.isMelded = isMelded;
}
public boolean isMelded() {
return isMelded;
}
public Card getTopHalfCard() {
return topHalfCard;
}
public void setTopHalfCard(Card topHalfCard, Game game) {
this.topHalfCard = topHalfCard;
this.topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
}
public int getTopLastZoneChangeCounter() {
return topLastZoneChangeCounter;
}
public void setTopLastZoneChangeCounter(int topLastZoneChangeCounter) {
this.topLastZoneChangeCounter = topLastZoneChangeCounter;
}
public Card getBottomHalfCard() {
return bottomHalfCard;
}
public void setbottomHalfCard(Card bottomHalfCard, Game game) {
this.bottomHalfCard = bottomHalfCard;
this.bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
}
public int getBottomLastZoneChangeCounter() {
return bottomLastZoneChangeCounter;
}
public void setBottomLastZoneChangeCounter(int bottomLastZoneChangeCounter) {
this.bottomLastZoneChangeCounter = bottomLastZoneChangeCounter;
}
@Override
public void assignNewId() {
super.assignNewId();
topHalfCard.assignNewId();
bottomHalfCard.assignNewId();
}
@Override
public void setCopy(boolean isCopy) {
super.setCopy(isCopy);
topHalfCard.setCopy(isCopy);
bottomHalfCard.setCopy(isCopy);
}
@Override
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, ArrayList<UUID> appliedEffects) {
if (this.isMelded()) {
// Initial move to battlefield
if (toZone == Zone.BATTLEFIELD) {
return this.putOntoBattlefield(game, Zone.EXILED, sourceId, this.getOwnerId(), false, false, appliedEffects);
} // Move when melded from the battlefield to elsewhere
else {
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), sourceId, this.getOwnerId(), Zone.BATTLEFIELD, toZone, appliedEffects);
if (!game.replaceEvent(event)) {
updateZoneChangeCounter(game);
switch (event.getToZone()) {
case GRAVEYARD:
game.getPlayer(this.getOwnerId()).putInGraveyard(topHalfCard, game, true);
game.getPlayer(this.getOwnerId()).putInGraveyard(bottomHalfCard, game, true);
break;
case HAND:
game.getPlayer(this.getOwnerId()).getHand().add(topHalfCard);
game.getPlayer(this.getOwnerId()).getHand().add(bottomHalfCard);
break;
case EXILED:
game.getExile().getPermanentExile().add(topHalfCard);
game.getExile().getPermanentExile().add(bottomHalfCard);
break;
case LIBRARY:
Player controller = game.getPlayer(this.getOwnerId());
if (controller != null) {
CardsImpl cardsToMove = new CardsImpl();
cardsToMove.add(topHalfCard);
cardsToMove.add(bottomHalfCard);
if (flag) {
controller.putCardsOnTopOfLibrary(cardsToMove, game, null, true);
} else {
controller.putCardsOnBottomOfLibrary(cardsToMove, game, null, true);
}
}
break;
default:
return false;
}
this.setMelded(false);
game.setZone(topHalfCard.getId(), event.getToZone());
game.setZone(bottomHalfCard.getId(), event.getToZone());
this.topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
this.bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
game.addSimultaneousEvent(event);
return true;
} else {
return false;
}
}
} else {
// Try to move the former meld cards after it has already left the battlefield.
// If the meld parts didn't move from that zone, move them instead of the meld card.
// Reset the local zcc so the meld card lose track of them.
boolean returnValue = false;
if (topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)) {
topHalfCard.moveToZone(toZone, sourceId, game, flag, appliedEffects);
topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
if (bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)) {
bottomHalfCard.moveToZone(toZone, sourceId, game, flag, appliedEffects);
bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
return returnValue;
}
}
@Override
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList<UUID> appliedEffects) {
if (this.isMelded()) {
// Move when melded from the battlefield to exile
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), sourceId, this.getOwnerId(), Zone.BATTLEFIELD, Zone.EXILED, appliedEffects);
if (!game.replaceEvent(event)) {
updateZoneChangeCounter(game);
switch (event.getToZone()) {
case GRAVEYARD:
game.getPlayer(this.getOwnerId()).putInGraveyard(topHalfCard, game, true);
game.getPlayer(this.getOwnerId()).putInGraveyard(bottomHalfCard, game, true);
break;
case HAND:
game.getPlayer(this.getOwnerId()).getHand().add(topHalfCard);
game.getPlayer(this.getOwnerId()).getHand().add(bottomHalfCard);
break;
case EXILED:
if (exileId == null) {
game.getExile().getPermanentExile().add(topHalfCard);
game.getExile().getPermanentExile().add(bottomHalfCard);
} else {
game.getExile().createZone(exileId, name).add(topHalfCard);
game.getExile().getExileZone(exileId).add(bottomHalfCard);
}
break;
case LIBRARY:
Player controller = game.getPlayer(this.getOwnerId());
if (controller != null) {
CardsImpl cardsToMove = new CardsImpl();
cardsToMove.add(topHalfCard);
cardsToMove.add(bottomHalfCard);
if (event.getFlag()) {
controller.putCardsOnTopOfLibrary(cardsToMove, game, null, true);
} else {
controller.putCardsOnBottomOfLibrary(cardsToMove, game, null, true);
}
}
break;
default:
return false;
}
this.setMelded(false);
game.setZone(topHalfCard.getId(), event.getToZone());
game.setZone(bottomHalfCard.getId(), event.getToZone());
this.topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
this.bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
game.addSimultaneousEvent(event);
return true;
} else {
return false;
}
} else {
// Try to move the former meld cards after it has already left the battlefield.
// If the meld parts didn't move from that zone, move them instead of the meld card.
// Reset the local zcc so the meld card lose track of them.
boolean returnValue = false;
if (topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)) {
topHalfCard.moveToExile(exileId, name, sourceId, game, appliedEffects);
topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
if (bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)) {
bottomHalfCard.moveToExile(exileId, name, sourceId, game, appliedEffects);
bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
return returnValue;
}
}
@Override
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList<UUID> appliedEffects) {
// Initial move to battlefield
if (this.isMelded()) {
ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, controllerId, Zone.EXILED, Zone.BATTLEFIELD, appliedEffects);
if (!game.replaceEvent(event) && event.getToZone() == Zone.BATTLEFIELD) {
updateZoneChangeCounter(game);
PermanentMeld permanent = new PermanentMeld(this, event.getPlayerId(), game); // controller can be replaced (e.g. Gather Specimens)
game.addPermanent(permanent);
game.setZone(objectId, Zone.BATTLEFIELD);
game.setScopeRelevant(true);
game.applyEffects();
boolean entered = permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
game.setScopeRelevant(false);
game.applyEffects();
if (entered) {
if (event.getFlag()) {
permanent.setTapped(true);
}
event.setTarget(permanent);
} else {
return false;
}
game.setZone(objectId, event.getToZone());
game.addSimultaneousEvent(event);
game.getExile().removeCard(this.topHalfCard, game);
game.getExile().removeCard(this.bottomHalfCard, game);
return true;
} else {
this.setMelded(false);
return false;
}
} else {
// Try to move the former meld cards after it has already left the battlefield.
// If the meld parts didn't move from that zone, move them instead of the meld card.
// Reset the local zcc so the meld card lose track of them.
boolean returnValue = false;
if (topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)) {
topHalfCard.moveToZone(Zone.BATTLEFIELD, sourceId, game, tapped, appliedEffects);
topLastZoneChangeCounter = topHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
if (bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)) {
bottomHalfCard.moveToZone(Zone.BATTLEFIELD, sourceId, game, tapped, appliedEffects);
bottomLastZoneChangeCounter = bottomHalfCard.getZoneChangeCounter(game);
returnValue = true;
}
return returnValue;
}
}
@Override
public void setOwnerId(UUID ownerId) {
super.setOwnerId(ownerId);
abilities.setControllerId(ownerId);
}
@Override
public int getConvertedManaCost() {
if (this.isCopy()) {
return 0;
} else {
return (this.topHalfCard != null ? this.topHalfCard.getConvertedManaCost() : 0)
+ (this.bottomHalfCard != null ? this.bottomHalfCard.getConvertedManaCost() : 0);
}
}
@Override
public void addCounters(Counter counter, Game game, ArrayList<UUID> appliedEffects) {
if (this.isMelded()) {
super.addCounters(counter, game, appliedEffects);
} else {
if (topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)) {
topHalfCard.addCounters(counter, game, appliedEffects);
}
if (bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)) {
bottomHalfCard.addCounters(counter, game, appliedEffects);
}
}
}
@Override
public void addCounters(String name, int amount, Game game, ArrayList<UUID> appliedEffects) {
if (this.isMelded()) {
super.addCounters(name, amount, game, appliedEffects);
} else {
if (topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)) {
topHalfCard.addCounters(name, amount, game, appliedEffects);
}
if (bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)) {
bottomHalfCard.addCounters(name, amount, game, appliedEffects);
}
}
}
}

View file

@ -47,6 +47,7 @@ import mage.abilities.effects.PreventionEffectData;
import mage.actions.impl.MageAction;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.MeldCard;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.constants.Duration;
@ -93,6 +94,10 @@ public interface Game extends MageItem, Serializable {
Collection<Card> getCards();
MeldCard getMeldCard(UUID meldId);
void addMeldCard(UUID meldId, MeldCard meldCard);
Object getCustomData();
void setCustomData(Object data);
@ -348,7 +353,7 @@ public interface Game extends MageItem, Serializable {
void setManaPaymentMode(UUID playerId, boolean autoPayment);
void setManaPaymentModeRestricted(UUID playerId, boolean autoPaymentRestricted);
void setUseFirstManaAbility(UUID playerId, boolean useFirstManaAbility);
void undo(UUID playerId);

Some files were not shown because too many files have changed in this diff Show more