Merge pull request #80 from magefree/master

merge
This commit is contained in:
theelk801 2017-09-23 17:30:43 -04:00 committed by GitHub
commit dafd75e1ab
50 changed files with 1118 additions and 505 deletions

View file

@ -42,9 +42,7 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
@ -53,44 +51,25 @@ import mage.target.common.TargetCardInHand;
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class AlexiZephyrMage extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("Target creatures");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public AlexiZephyrMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SPELLSHAPER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
//TODO: Make ability properly copiable
// {X}{U}, {tap}, Discard two cards: Return X target creatures to their owners' hands.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{X}{U}"));
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards"))));
this.addAbility(ability);
originalId = ability.getOriginalId();
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
ability.getTargets().clear();
ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter));
}
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURES));
this.addAbility(ability);
}
public AlexiZephyrMage(final AlexiZephyrMage card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -40,10 +40,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
import mage.target.TargetPermanent;
/**
*
@ -51,7 +51,12 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class AncientHellkite extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("creature defending player controls");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(new DefendingPlayerControlsPredicate());
}
public AncientHellkite(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}");
@ -60,29 +65,14 @@ public class AncientHellkite extends CardImpl {
this.power = new MageInt(6);
this.toughness = new MageInt(6);
//TODO: Make ability properly copiable
this.addAbility(FlyingAbility.getInstance());
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}"), SourceAttackingCondition.instance);
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls")));
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
public AncientHellkite(final AncientHellkite card) {
super(card);
this.originalId = card.originalId;
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
ability.getTargets().clear();
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls");
UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId());
filter.add(new ControllerIdPredicate(defenderId));
TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
ability.addTarget(target);
}
}
@Override

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 LIAB8LE 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.b;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author L_J
*/
public class BakisCurse extends CardImpl {
public BakisCurse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}");
// Baki's Curse deals 2 damage to each creature for each Aura attached to that creature.
this.getSpellAbility().addEffect(new BakisCurseEffect());
}
public BakisCurse(final BakisCurse card) {
super(card);
}
@Override
public BakisCurse copy() {
return new BakisCurse(this);
}
}
class BakisCurseEffect extends OneShotEffect {
public BakisCurseEffect() {
super(Outcome.Detriment);
staticText = "Baki's Curse deals 2 damage to each creature for each Aura attached to that creature.";
}
public BakisCurseEffect(final BakisCurseEffect effect) {
super(effect);
}
@Override
public BakisCurseEffect copy() {
return new BakisCurseEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) {
int count = 0;
List<UUID> attachments = creature.getAttachments();
for (UUID attachmentId : attachments) {
Permanent attached = game.getPermanent(attachmentId);
if (attached != null && attached.getSubtype(game).contains(SubType.AURA)) {
count++;
}
}
creature.damage(count * 2, source.getId(), game, false, true);
}
return true;
}
}

View file

@ -37,10 +37,10 @@ import mage.abilities.effects.common.UntapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.target.common.TargetLandPermanent;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
/**
*
@ -48,33 +48,21 @@ import mage.target.common.TargetLandPermanent;
*/
public class CandelabraOfTawnos extends CardImpl {
private final UUID originalId;
public CandelabraOfTawnos(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
//TODO: Make ability properly copiable
// {X}, {T}: Untap X target lands.
Effect effect = new UntapTargetEffect();
effect.setText("untap X target lands");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)){
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
ability.addTarget(new TargetLandPermanent(xValue, xValue, new FilterLandPermanent(), false));
}
}
public CandelabraOfTawnos(final CandelabraOfTawnos card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -39,15 +39,15 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPlayer;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.other.PlayerIdPredicate;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.targetpointer.FixedTarget;
@ -58,7 +58,11 @@ import mage.target.targetpointer.FixedTarget;
*/
public class CrownOfDoom extends CardImpl {
private UUID abilityId;
private static final FilterPlayer filter = new FilterPlayer("player other than {this}'s owner");
static {
filter.add(new CrownOfDoomPredicate());
}
public CrownOfDoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
@ -71,27 +75,12 @@ public class CrownOfDoom extends CardImpl {
//TODO: Make ability properly copiable
// {2}: Target player other than Crown of Doom's owner gains control of it. Activate this ability only during your turn.
Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new CrownOfDoomEffect(), new ManaCostsImpl("{2}"), MyTurnCondition.instance);
ability.addTarget(new TargetPlayer(1, 1, false, new FilterPlayer("player other than Crown of Doom's owner")));
abilityId = ability.getOriginalId();
ability.addTarget(new TargetPlayer(1, 1, false, filter));
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(abilityId)) {
Card sourceCard = game.getCard(ability.getSourceId());
if (sourceCard != null) {
ability.getTargets().clear();
FilterPlayer filter = new FilterPlayer("player other than " + sourceCard.getIdName() + "'s owner");
filter.add(Predicates.not(new PlayerIdPredicate(sourceCard.getOwnerId())));
ability.addTarget(new TargetPlayer(1, 1, false, filter));
}
}
}
public CrownOfDoom(final CrownOfDoom card) {
super(card);
this.abilityId = card.abilityId;
}
@Override
@ -100,6 +89,27 @@ public class CrownOfDoom extends CardImpl {
}
}
class CrownOfDoomPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Player>> {
public CrownOfDoomPredicate() {
}
@Override
public boolean apply(ObjectSourcePlayer<Player> input, Game game) {
Player targetPlayer = input.getObject();
Permanent sourceObject = game.getPermanentOrLKIBattlefield(input.getSourceId());
if (targetPlayer == null || sourceObject == null) {
return false;
}
return !targetPlayer.getId().equals(sourceObject.getOwnerId());
}
@Override
public String toString() {
return "Owner(" + ')';
}
}
class CrownOfDoomEffect extends OneShotEffect {
public CrownOfDoomEffect() {

View file

@ -28,7 +28,6 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -37,10 +36,9 @@ import mage.abilities.effects.common.NameACardEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.target.TargetSpell;
/**
@ -49,38 +47,23 @@ import mage.target.TargetSpell;
*/
public class DeclarationOfNaught extends CardImpl {
private final UUID originalId;
static final private FilterSpell filter = new FilterSpell("spell with the chosen name");
public DeclarationOfNaught(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}");
// As Declaration of Naught enters the battlefield, name a card.
this.addAbility(new AsEntersBattlefieldAbility(new NameACardEffect(NameACardEffect.TypeOfName.ALL)));
//TODO: Make ability properly copiable
// {U}: Counter target spell with the chosen name.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{U}"));
ability.setTargetAdjustment(TargetAdjustment.CHOSEN_NAME);
ability.addTarget(new TargetSpell(filter));
originalId = ability.getOriginalId();
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
ability.getTargets().clear();
FilterSpell filter2 = new FilterSpell("spell with the chosen name");
filter2.add(new NamePredicate((String) game.getState().getValue(ability.getSourceId().toString() + NameACardEffect.INFO_KEY)));
TargetSpell target = new TargetSpell(1, filter2);
ability.addTarget(target);
}
}
public DeclarationOfNaught(final DeclarationOfNaught card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -37,14 +37,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.Target;
import mage.target.TargetPermanent;
/**
@ -53,44 +50,31 @@ import mage.target.TargetPermanent;
*/
public class DeepfireElemental extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("artifact or creature with converted mana cost X");
static {
filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE)));
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE)
));
}
public DeepfireElemental(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{R}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
//TODO: Make ability properly copiable
// {X}{X}{1}: Destroy target artifact or creature with converted mana cost X.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{1}"));
ability.addTarget(new TargetPermanent(filter));
originalId = ability.getOriginalId();
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_PERM);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
ability.getTargets().clear();
FilterPermanent newFilter = filter.copy();
newFilter.setMessage(new StringBuilder("artifact or creature with converted mana cost {").append(ability.getManaCostsToPay().getX()).append('}').toString());
newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, ability.getManaCostsToPay().getX()));
Target target = new TargetPermanent(newFilter);
ability.addTarget(target);
}
}
public DeepfireElemental(final DeepfireElemental card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -38,43 +38,29 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.target.common.TargetLandPermanent;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
/**
*
* @author fireshoes
*/
public class FloodwaterDam extends CardImpl {
private final UUID originalId;
public FloodwaterDam(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
//TODO: Make ability properly copiable
// {X}{X}{1}, {tap}: Tap X target lands.
Effect effect = new TapTargetEffect();
effect.setText("tap X target lands");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}{X}{1}"));
ability.addCost(new TapSourceCost());
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)){
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
ability.addTarget(new TargetLandPermanent(xValue, xValue, new FilterLandPermanent(), false));
}
}
public FloodwaterDam(final FloodwaterDam card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -39,17 +39,15 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCardInOpponentsGraveyard;
/**
@ -57,7 +55,13 @@ import mage.target.common.TargetCardInOpponentsGraveyard;
*/
public class GethLordOfTheVault extends CardImpl {
private final UUID originalId;
private static final FilterCard filter = new FilterCard("artifact or creature card with converted mana cost X from an opponent's graveyard");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE)));
}
public GethLordOfTheVault(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
@ -69,33 +73,16 @@ public class GethLordOfTheVault extends CardImpl {
// Intimidate
this.addAbility(IntimidateAbility.getInstance());
//TODO: Make ability properly copiable
// {X}{B}: Put target artifact or creature card with converted mana cost X from an opponent's graveyard onto the battlefield under your control tapped.
// Then that player puts the top X cards of his or her library into his or her graveyard.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GethLordOfTheVaultEffect(), new ManaCostsImpl("{X}{B}"));
originalId = ability.getOriginalId();
ability.addTarget(new TargetCardInOpponentsGraveyard(new FilterCard("artifact or creature card with converted mana cost X from an opponent's graveyard")));
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_GY_CARD);
ability.addTarget(new TargetCardInOpponentsGraveyard(filter));
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterCard filter = new FilterCard("artifact or creature card with converted mana cost " + xValue + " from an opponent's graveyard");
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE)));
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
Target target = new TargetCardInOpponentsGraveyard(filter);
ability.addTarget(target);
}
}
public GethLordOfTheVault(final GethLordOfTheVault card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -37,14 +37,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.common.FilterArtifactPermanent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.Target;
import mage.target.TargetPermanent;
/**
@ -53,39 +50,29 @@ import mage.target.TargetPermanent;
*/
public class GorillaShaman extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("noncreature artifact with converted mana cost X");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public GorillaShaman(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.APE);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
//TODO: Make ability properly copiable
// {X}{X}{1}: Destroy target noncreature artifact with converted mana cost X.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{1}"));
ability.addTarget(new TargetPermanent(new FilterArtifactPermanent("noncreature artifact with converted mana cost X")));
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(filter));
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_PERM);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterArtifactPermanent filter = new FilterArtifactPermanent(new StringBuilder("noncreature artifact with converted mana cost ").append(xValue).toString());
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
Target target = new TargetPermanent(filter);
ability.addTarget(target);
}
}
public GorillaShaman(final GorillaShaman card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -46,6 +46,7 @@ import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
@ -53,6 +54,7 @@ import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.other.AuraCardCanAttachToPermanentId;
import mage.filter.predicate.other.OwnerPredicate;
import mage.filter.predicate.permanent.AttachedToPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -62,12 +64,17 @@ import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author jeffwadsworth
* @author jeffwadsworth, TheElk801
*/
public class HakimLoreweaver extends CardImpl {
private final static String rule = "Return target Aura card from your graveyard to the battlefield attached to Hakim, Loreweaver. Activate this ability only during your upkeep and only if Hakim isn't enchanted.";
UUID originalId;
private static final FilterCard filter = new FilterCard("target Aura card from your graveyard");
static {
filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
filter.add(new SubtypePredicate(SubType.AURA));
filter.add(new OwnerPredicate(TargetController.YOU));
}
public HakimLoreweaver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
@ -81,11 +88,13 @@ public class HakimLoreweaver extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
//TODO: Make ability properly copiable
// {U}{U}: Return target Aura card from your graveyard to the battlefield attached to Hakim, Loreweaver. Activate this ability only during your upkeep and only if Hakim isn't enchanted.
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new HakimLoreweaverEffect(), new ManaCostsImpl("{U}{U}"), new HakimLoreweaverCondition(), rule);
ability.addTarget(new TargetCardInYourGraveyard());
originalId = ability.getOriginalId();
Ability ability = new ConditionalActivatedAbility(
Zone.BATTLEFIELD,
new HakimLoreweaverEffect(),
new ManaCostsImpl("{U}{U}"),
new HakimLoreweaverCondition());
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
// {U}{U}, {tap}: Destroy all Auras attached to Hakim.
@ -101,26 +110,8 @@ public class HakimLoreweaver extends CardImpl {
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
Player controller = game.getPlayer(ability.getControllerId());
if (controller != null) {
ability.getTargets().clear();
FilterCard filterAuraCard = new FilterCard("target Aura card from your graveyard");
filterAuraCard.add(new CardTypePredicate(CardType.ENCHANTMENT));
filterAuraCard.add(new SubtypePredicate(SubType.AURA));
filterAuraCard.add(new AuraCardCanAttachToPermanentId(ability.getSourceId()));
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filterAuraCard);
ability.addTarget(target);
}
}
}
public HakimLoreweaver(final HakimLoreweaver card) {
super(card);
this.originalId = card.originalId;
}
@Override
@ -133,7 +124,7 @@ class HakimLoreweaverEffect extends OneShotEffect {
public HakimLoreweaverEffect() {
super(Outcome.Benefit);
this.staticText = "Return target Aura card from your graveyard to the battlefield attached to {this}. Activate this ability only during your upkeep and only if Hakim isn't enchanted";
this.staticText = "Return target Aura card from your graveyard to the battlefield attached to {this}.";
}
public HakimLoreweaverEffect(final HakimLoreweaverEffect effect) {
@ -153,7 +144,8 @@ class HakimLoreweaverEffect extends OneShotEffect {
if (controller != null
&& hakimLoreweaver != null
&& controller.canRespond()
&& targetAuraCard != null) {
&& targetAuraCard != null
&& new AuraCardCanAttachToPermanentId(hakimLoreweaver.getId()).apply(targetAuraCard, game)) {
Target target = targetAuraCard.getSpellAbility().getTargets().get(0);
if (target != null) {
game.getState().setValue("attachTo:" + targetAuraCard.getId(), hakimLoreweaver);
@ -188,4 +180,9 @@ class HakimLoreweaverCondition implements Condition {
}
return false;
}
@Override
public String toString() {
return "only during your upkeep and only if {this} isn't enchanted";
}
}

View file

@ -38,12 +38,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.common.FilterArtifactPermanent;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.Target;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
/**
@ -51,7 +49,11 @@ import mage.target.TargetPermanent;
*/
public class HearthKami extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("artifact with converted mana cost X");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
}
public HearthKami(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
@ -60,30 +62,16 @@ public class HearthKami extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(1);
//TODO: Make ability properly copiable
// {X}, Sacrifice Hearth Kami: Destroy target artifact with converted mana cost X.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(new FilterArtifactPermanent("artifact with converted mana cost X")));
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(filter));
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_PERM);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterArtifactPermanent filter = new FilterArtifactPermanent(new StringBuilder("artifact with converted mana cost ").append(xValue).toString());
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
Target target = new TargetPermanent(filter);
ability.addTarget(target);
}
}
public HearthKami(final HearthKami card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -33,6 +33,7 @@ import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
@ -49,6 +50,8 @@ import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.watchers.Watcher;
@ -115,7 +118,7 @@ class HopeOfGhirapurCantCastEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
MageObject mageObject = source.getSourceObject(game);
if (mageObject != null) {
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
}
@ -153,7 +156,7 @@ class HopeOfGhirapurPlayerLostLifePredicate implements ObjectSourcePlayerPredica
}
HopeOfGhirapurCombatDamageWatcher watcher = (HopeOfGhirapurCombatDamageWatcher) game.getState().getWatchers().get(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName());
if (watcher != null) {
return watcher.playerGotCombatDamage(input.getSourceId(), input.getObject().getId());
return watcher.playerGotCombatDamage(input.getSourceId(), input.getObject().getId(), game);
}
return false;
}
@ -161,7 +164,7 @@ class HopeOfGhirapurPlayerLostLifePredicate implements ObjectSourcePlayerPredica
class HopeOfGhirapurCombatDamageWatcher extends Watcher {
private final HashMap<UUID, Set<UUID>> combatDamagedPlayers = new HashMap<>();
private final HashMap<MageObjectReference, Set<UUID>> combatDamagedPlayers = new HashMap<>();
public HopeOfGhirapurCombatDamageWatcher() {
super(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName(), WatcherScope.GAME);
@ -169,10 +172,10 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
public HopeOfGhirapurCombatDamageWatcher(final HopeOfGhirapurCombatDamageWatcher watcher) {
super(watcher);
for (UUID damagerId : watcher.combatDamagedPlayers.keySet()) {
for (MageObjectReference damager : watcher.combatDamagedPlayers.keySet()) {
Set<UUID> players = new HashSet<>();
players.addAll(watcher.combatDamagedPlayers.get(damagerId));
this.combatDamagedPlayers.put(damagerId, players);
players.addAll(watcher.combatDamagedPlayers.get(damager));
this.combatDamagedPlayers.put(damager, players);
}
}
@ -184,13 +187,13 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.DAMAGED_PLAYER && ((DamagedPlayerEvent) event).isCombatDamage()) {
UUID damagerId = event.getSourceId();
MageObjectReference damager = new MageObjectReference(event.getSourceId(), game);
Set<UUID> players;
if (combatDamagedPlayers.containsKey(damagerId)) {
players = combatDamagedPlayers.get(damagerId);
if (combatDamagedPlayers.containsKey(damager)) {
players = combatDamagedPlayers.get(damager);
} else {
players = new HashSet<>();
combatDamagedPlayers.put(damagerId, players);
combatDamagedPlayers.put(damager, players);
}
players.add(event.getTargetId());
}
@ -204,9 +207,17 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
* @param playerId
* @return
*/
public boolean playerGotCombatDamage(UUID objectId, UUID playerId) {
if (combatDamagedPlayers.containsKey(objectId)) {
return combatDamagedPlayers.get(objectId).contains(playerId);
public boolean playerGotCombatDamage(UUID objectId, UUID playerId, Game game) {
StackObject stackObject = game.getState().getStack().getStackObject(objectId);
MageObjectReference mor;
if (stackObject != null && stackObject instanceof StackAbility) {
// This is neccessary because the source object was sacrificed as cost and the correct zone change counter for target calid check can only be get from stack
mor = new MageObjectReference(objectId, ((StackAbility) stackObject).getSourceObjectZoneChangeCounter(), game);
} else {
mor = new MageObjectReference(objectId, game);
}
if (combatDamagedPlayers.containsKey(mor)) {
return combatDamagedPlayers.get(mor).contains(playerId);
}
return false;
}

View file

@ -37,15 +37,12 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.TargetAdjustment;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
@ -53,38 +50,24 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class LegacysAllure extends CardImpl {
private final UUID originalId;
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than or equal to the number of treasure counters on {this}");
public LegacysAllure(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}");
// At the beginning of your upkeep, you may put a treasure counter on Legacy's Allure.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(new Counter("treasure")), TargetController.YOU, true));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.TREASURE.createInstance(), true), TargetController.YOU, true));
// Sacrifice Legacy's Allure: Gain control of target creature with power less than or equal to the number of treasure counters on Legacy's Allure.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainControlTargetEffect(Duration.EndOfGame, true), new SacrificeSourceCost());
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with power less than or equal to the number of treasure counters on " + getLogName())));
originalId = ability.getOriginalId();
ability.addTarget(new TargetCreaturePermanent(0, 0, filter, false));
ability.setTargetAdjustment(TargetAdjustment.TREASURE_COUNTER_POWER);
this.addAbility(ability);
}
public LegacysAllure(final LegacysAllure card) {
super(card);
this.originalId = card.originalId;
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
int numbCounters = sourcePermanent.getCounters(game).getCount("treasure");
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than or equal to the number of treasure counters on " + getLogName());
filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, numbCounters + 1));
ability.getTargets().clear();
ability.getTargets().add(new TargetCreaturePermanent(filter));
}
}
}
@Override

View file

@ -75,6 +75,7 @@ public class LilianaDefiantNecromancer extends CardImpl {
// +2: Each player discards a card.
this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2));
//TODO: Make ability properly copiable
// -X: Return target nonlegendary creature with converted mana cost X from your graveyard to the battlefield.
Ability ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect());
ability2Id = ability.getOriginalId();

View file

@ -40,22 +40,21 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
@ -63,10 +62,14 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class LinessaZephyrMage extends CardImpl {
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("creature with converted mana cost X");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public LinessaZephyrMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
@ -74,12 +77,11 @@ public class LinessaZephyrMage extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
//TODO: Make ability properly copiable
// {X}{U}{U}, {tap}: Return target creature with converted mana cost X to its owner's hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{X}{U}{U}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(filter));
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_PERM);
this.addAbility(ability);
// Grandeur - Discard another card named Linessa, Zephyr Mage: Target player returns a creature he or she controls to its owner's hand, then repeats this process for an artifact, an enchantment, and a land.
@ -90,18 +92,6 @@ public class LinessaZephyrMage extends CardImpl {
public LinessaZephyrMage(final LinessaZephyrMage card) {
super(card);
this.originalId = card.originalId;
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost " + xValue);
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
ability.getTargets().add(new TargetCreaturePermanent(filter));
}
}
@Override

View file

@ -39,48 +39,36 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.common.TargetLandPermanent;
import mage.target.TargetPermanent;
/**
* @author duncant
*/
public class MagusOfTheCandelabra extends CardImpl {
private final UUID originalId;
public MagusOfTheCandelabra(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
//TODO: Make ability properly copiable
// {X}, {T}: Untap X target lands.
Effect effect = new UntapTargetEffect();
effect.setText("untap X target lands");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)){
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
ability.addTarget(new TargetLandPermanent(xValue, xValue, StaticFilters.FILTER_LANDS, false));
}
}
public MagusOfTheCandelabra(final MagusOfTheCandelabra card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -33,19 +33,17 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
import mage.target.TargetPermanent;
/**
*
@ -53,48 +51,32 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class MinamoSightbender extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power X or less");
private final UUID originalId;
private static final FilterPermanent filter = new FilterPermanent("creature with power X or less");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public MinamoSightbender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
//TODO: Make ability properly copiable
// {X}, {T}: Target creature with power X or less can't be blocked this turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedTargetEffect(), new ManaCostsImpl("{X}"));
Target target = new TargetCreaturePermanent(filter);
Target target = new TargetPermanent(filter);
ability.setTargetAdjustment(TargetAdjustment.X_POWER_LEQ);
ability.addTarget(target);
ability.addCost(new TapSourceCost());
originalId = ability.getOriginalId();
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
for (Effect effect : ability.getEffects()) {
if (effect instanceof CantBeBlockedTargetEffect) {
int manaX = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterCreaturePermanent newFilter = new FilterCreaturePermanent(new StringBuilder("creature with power ").append(manaX).append(" or less").toString());
filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, manaX + 1));
Target target = new TargetCreaturePermanent(newFilter);
ability.addTarget(target);
break;
}
}
}
}
public MinamoSightbender(final MinamoSightbender card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -37,43 +37,31 @@ import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.common.TargetLandPermanent;
import mage.target.TargetPermanent;
/**
*
* @author fireshoes
*/
public class MishrasHelix extends CardImpl {
private final UUID originalId;
public MishrasHelix(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
//TODO: Make ability properly copiable
// {X}, {tap}: Tap X target lands.
Effect effect = new TapTargetEffect("X target lands");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
originalId = ability.getOriginalId();
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)){
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
ability.addTarget(new TargetLandPermanent(xValue, xValue, StaticFilters.FILTER_LANDS, false));
}
}
public MishrasHelix(final MishrasHelix card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -30,6 +30,7 @@ package mage.cards.o;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -38,10 +39,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterLandCard;
import mage.filter.common.FilterBasicLandCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@ -94,8 +95,8 @@ class OldGrowthDryadsEffect extends OneShotEffect {
Set<Player> playersThatSearched = new HashSet<>(1);
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null && opponent.chooseUse(Outcome.PutCreatureInPlay, "Search your library for a creature card and put it onto the battlefield?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(new FilterLandCard());
if (opponent != null && opponent.chooseUse(Outcome.PutLandInPlay, "Search your library for a basic land card and put it onto the battlefield tapped?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard());
if (opponent.searchLibrary(target, game)) {
Card targetCard = opponent.getLibrary().getCard(target.getFirstTarget(), game);
if (targetCard != null) {

View file

@ -29,7 +29,6 @@ package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -44,23 +43,21 @@ import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.target.TargetPermanent;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.constants.TargetAdjustment;
/**
*
* @author jeffwadsworth
*/
public class PentarchPaladin extends CardImpl {
private final UUID originalId;
FilterPermanent filter = new FilterPermanent("permanent of the chosen color.");
public PentarchPaladin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(3);
@ -71,36 +68,21 @@ public class PentarchPaladin extends CardImpl {
// As Pentarch Paladin enters the battlefield, choose a color.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Detriment)));
// {W}{W}, {tap}: Destroy target permanent of the chosen color.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{W}{W}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPermanent(filter));
originalId = ability.getOriginalId();
ability.setTargetAdjustment(TargetAdjustment.CHOSEN_COLOR);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
ObjectColor color = (ObjectColor) game.getState().getValue(ability.getSourceId() + "_color");
if (ability.getOriginalId().equals(originalId)
&& color != null) {
ability.getTargets().clear();
FilterPermanent filter = new FilterPermanent("permanent of the chosen color.");
filter.add(new ColorPredicate(color));
TargetPermanent target = new TargetPermanent(filter);
ability.addTarget(target);
}
}
public PentarchPaladin(final PentarchPaladin card) {
super(card);
this.originalId = card.originalId;
}
@Override
public PentarchPaladin copy() {
return new PentarchPaladin(this);
}
}
}

View file

@ -38,14 +38,12 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.Target;
import mage.target.TargetPermanent;
/**
@ -54,43 +52,28 @@ import mage.target.TargetPermanent;
*/
public class Plaguebearer extends CardImpl {
private final UUID originalId;
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature");
private static final FilterPermanent filter = new FilterPermanent("nonblack creature with converted mana cost X");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
}
public Plaguebearer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
//TODO: Make ability properly copiable
// {X}{X}{B}: Destroy target nonblack creature with converted mana cost X.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{B}"));
ability.addTarget(new TargetPermanent(filter));
originalId = ability.getOriginalId();
ability.setTargetAdjustment(TargetAdjustment.X_CMC_EQUAL_PERM);
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterCreaturePermanent filter = new FilterCreaturePermanent(new StringBuilder("nonblack creature with converted mana cost ").append(xValue).toString());
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
Target target = new TargetPermanent(filter);
ability.addTarget(target);
}
}
public Plaguebearer(final Plaguebearer card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -0,0 +1,80 @@
/*
* 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.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public class Recantation extends CardImpl {
public Recantation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
// At the beginning of your upkeep, you may put a verse counter on Recantation.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// {U}, Sacrifice Recantation: Return up to X target permanents to their owners' hands, where X is the number of verse counters on Recantation.
Effect effect = new ReturnToHandTargetEffect(true);
effect.setText("Return up to X target permanents to their owners' hands, where X is the number of verse counters on {this}.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{U}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(0, 0, new FilterPermanent("up to X target permanents, where X is the number of verse counters on {this}."), false));
ability.setTargetAdjustment(TargetAdjustment.VERSE_COUNTER_TARGETS);
this.addAbility(ability);
}
public Recantation(final Recantation card) {
super(card);
}
@Override
public Recantation copy() {
return new Recantation(this);
}
}

View file

@ -0,0 +1,87 @@
/*
* 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.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public class RumblingCrescendo extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("up to X target lands, where X is the number of verse counters on {this}");
static {
filter.add(new CardTypePredicate(CardType.LAND));
}
public RumblingCrescendo(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}");
// At the beginning of your upkeep, you may put a verse counter on Rumbling Crescendo.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// {R}, Sacrifice Rumbling Crescendo: Destroy up to X target lands, where X is the number of verse counters on Rumbling Crescendo.
Effect effect = new DestroyTargetEffect(true);
effect.setText("Destroy up to X target lands, where X is the number of verse counters on {this}.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{R}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(0, 0, filter, false));
ability.setTargetAdjustment(TargetAdjustment.VERSE_COUNTER_TARGETS);
this.addAbility(ability);
}
public RumblingCrescendo(final RumblingCrescendo card) {
super(card);
}
@Override
public RumblingCrescendo copy() {
return new RumblingCrescendo(this);
}
}

View file

@ -0,0 +1,91 @@
/*
* 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.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public class SerrasLiturgy extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("up to X target artifacts and/or enchantments, where X is the number of verse counters on {this}");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.ENCHANTMENT)
));
}
public SerrasLiturgy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
// At the beginning of your upkeep, you may put a verse counter on Serra's Liturgy.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// {W}, Sacrifice Serra's Liturgy: Destroy up to X target artifacts and/or enchantments, where X is the number of verse counters on Serra's Liturgy.
Effect effect = new DestroyTargetEffect(true);
effect.setText("Destroy up to X target artifacts and/or enchantments, where X is the number of verse counters on {this}.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{W}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(0, 0, filter, false));
ability.setTargetAdjustment(TargetAdjustment.VERSE_COUNTER_TARGETS);
this.addAbility(ability);
}
public SerrasLiturgy(final SerrasLiturgy card) {
super(card);
}
@Override
public SerrasLiturgy copy() {
return new SerrasLiturgy(this);
}
}

View file

@ -62,14 +62,16 @@ import mage.target.common.TargetCardInYourGraveyard;
public class SwordOfLightAndShadow extends CardImpl {
public SwordOfLightAndShadow(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+2 and has protection from white and from black.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.WHITE, ObjectColor.BLACK), AttachmentType.EQUIPMENT)));
// Whenever equipped creature deals combat damage to a player, you gain 3 life and you may return up to one target creature card from your graveyard to your hand.
this.addAbility(new SwordOfLightAndShadowAbility());
Ability ability = new SwordOfLightAndShadowAbility();
ability.addTarget(new TargetCardInYourGraveyard(0, 1, new FilterCreatureCard("creature card from your graveyard")));
this.addAbility(ability);
// Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));
}
@ -82,22 +84,6 @@ public class SwordOfLightAndShadow extends CardImpl {
public SwordOfLightAndShadow copy() {
return new SwordOfLightAndShadow(this);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability instanceof SwordOfLightAndShadowAbility) {
Player controller = game.getPlayer(ability.getControllerId());
if (controller != null) {
// Target may only be added if possible target exists. Else the gain life effect won't trigger, because there is no valid target for the
// return to hand ability
if (controller.getGraveyard().count(new FilterCreatureCard(), ability.getSourceId(), ability.getControllerId(), game) > 0) {
ability.addTarget(new TargetCardInYourGraveyard(0, 1, new FilterCreatureCard("creature card from your graveyard")));
}
}
}
}
}
class SwordOfLightAndShadowAbility extends TriggeredAbilityImpl {

View file

@ -40,11 +40,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.target.TargetPermanent;
/**
@ -52,54 +52,42 @@ import mage.target.TargetPermanent;
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class SynodArtificer extends CardImpl {
private final UUID tapId;
private final UUID untapId;
private static final FilterPermanent filter = new FilterPermanent("Target noncreature artifacts");
private static final FilterPermanent filter = new FilterPermanent("noncreature artifacts");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public SynodArtificer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.VEDALKEN);
this.subtype.add(SubType.ARTIFICER);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
//TODO: Make ability properly copiable
// {X}, {tap}: Tap X target noncreature artifacts.
Effect tapEffect = new TapTargetEffect();
tapEffect.setText("Tap X target noncreature artifacts.");
Ability tapAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, tapEffect, new ManaCostsImpl("{X}"));
tapAbility.addCost(new TapSourceCost());
tapAbility.addCost(new TapSourceCost());
tapAbility.setTargetAdjustment(TargetAdjustment.X_TARGETS);
tapAbility.addTarget(new TargetPermanent(filter));
this.addAbility(tapAbility);
// {X}, {tap}: Untap X target noncreature artifacts.
Effect untapEffect = new UntapTargetEffect();
untapEffect.setText("Untap X target noncreature artifacts.");
Ability untapAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, untapEffect, new ManaCostsImpl("{X}"));
untapAbility.addCost(new TapSourceCost());
untapAbility.setTargetAdjustment(TargetAdjustment.X_TARGETS);
untapAbility.addTarget(new TargetPermanent(filter));
this.addAbility(untapAbility);
tapId = tapAbility.getOriginalId();
untapId = untapAbility.getOriginalId();
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(tapId) || ability.getOriginalId().equals(untapId)) {
ability.getTargets().clear();
ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter));
}
}
public SynodArtificer(final SynodArtificer card) {
super(card);
this.tapId = card.tapId;
this.untapId = card.untapId;
}
@Override

View file

@ -0,0 +1,84 @@
/*
* 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.t;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.OrCost;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.TargetSpell;
/**
*
* @author L_J
*/
public class TidalControl extends CardImpl {
private static final FilterSpell filter = new FilterSpell("red or green spell");
static{
filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN)));
}
public TidalControl(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
// Cumulative upkeep-Pay {2}.
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}")));
// Pay 2 life or {2}: Counter target red or green spell. Any player may activate this ability.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new OrCost(new PayLifeCost(2), new ManaCostsImpl("{2}"), "pay 2 life or pay {2}"));
ability.addTarget(new TargetSpell(filter));
ability.setMayActivate(TargetController.ANY);
ability.addEffect(new InfoEffect("Any player may activate this ability"));
this.addAbility(ability);
}
public TidalControl(final TidalControl card) {
super(card);
}
@Override
public TidalControl copy() {
return new TidalControl(this);
}
}

View file

@ -51,13 +51,18 @@ import mage.target.common.TargetCreatureOrPlayer;
public class TorchSong extends CardImpl {
public TorchSong(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
// At the beginning of your upkeep, you may put a verse counter on Torch Song.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// {2}{R}, Sacrifice Torch Song: Torch Song deals X damage to target creature or player, where X is the number of verse counters on Torch Song.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new CountersSourceCount(CounterType.VERSE)), new ManaCostsImpl("{2}{R}"));
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new DamageTargetEffect(new CountersSourceCount(CounterType.VERSE)),
new ManaCostsImpl("{2}{R}")
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);

View file

@ -40,16 +40,15 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
import mage.target.TargetPermanent;
/**
*
@ -57,48 +56,33 @@ import mage.util.CardUtil;
*/
public class VileRequiem extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("up to X target nonblack creatures, where X is the number of verse counters on {this}");
private static final FilterPermanent filter = new FilterPermanent("up to X target nonblack creatures, where X is the number of verse counters on {this}");
static {
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
filter.add(new CardTypePredicate(CardType.CREATURE));
}
private final UUID originalId;
public VileRequiem(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}");
this.color.setBlack(true);
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
// At the beginning of your upkeep, you may put a verse counter on Vile Requiem.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true ), TargetController.YOU, true));
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// {1}{B}, Sacrifice Vile Requiem: Destroy up to X target nonblack creatures, where X is the number of verse counters on Vile Requiem. They can't be regenerated.
Effect effect = new DestroyTargetEffect(true);
effect.setText("Destroy up to X target nonblack creatures, where X is the number of verse counters on {this}. They can't be regenerated");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{B}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreaturePermanent(0,0,filter, false));
ability.addTarget(new TargetPermanent(0, 0, filter, false));
ability.setTargetAdjustment(TargetAdjustment.VERSE_COUNTER_TARGETS);
this.addAbility(ability);
originalId = ability.getOriginalId();
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
int numberCounters = sourcePermanent.getCounters(game).getCount(CounterType.VERSE);
ability.getTargets().clear();
FilterCreaturePermanent newFilter = filter.copy();
newFilter.setMessage(new StringBuilder("up to ").append(CardUtil.numberToText(numberCounters)).append(" target nonblack creatures").toString());
ability.addTarget(new TargetCreaturePermanent(0,numberCounters,newFilter, false));
}
}
}
public VileRequiem(final VileRequiem card) {
super(card);
this.originalId = card.originalId;
}
@Override

View file

@ -0,0 +1,73 @@
/*
* 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.w;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BlocksTriggeredAbility;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author L_J
*/
public class WallOfJunk extends CardImpl {
public WallOfJunk(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}");
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(7);
// Defender (This creature can't attack.)
this.addAbility(DefenderAbility.getInstance());
// When Wall of Junk blocks, return it to its owner's hand at end of combat.
Effect effect = new CreateDelayedTriggeredAbilityEffect(
new AtTheEndOfCombatDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)));
effect.setText("return it to its owner's hand at end of combat");
this.addAbility(new BlocksTriggeredAbility(effect, false));
}
public WallOfJunk(final WallOfJunk card) {
super(card);
}
@Override
public WallOfJunk copy() {
return new WallOfJunk(this);
}
}

View file

@ -0,0 +1,82 @@
/*
* 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.w;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.dynamicvalue.common.CountersSourceCount;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public class WarDance extends CardImpl {
public WarDance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}");
// At the beginning of your upkeep, you may put a verse counter on War Dance.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true));
// Sacrifice War Dance: Target creature gets +X/+X until end of turn, where X is the number of verse counters on War Dance.
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new BoostTargetEffect(
new CountersSourceCount(CounterType.VERSE),
new CountersSourceCount(CounterType.VERSE),
Duration.EndOfTurn
),
new SacrificeSourceCost()
);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public WarDance(final WarDance card) {
super(card);
}
@Override
public WarDance copy() {
return new WarDance(this);
}
}

View file

@ -145,6 +145,7 @@ public class Alliances extends ExpansionSet {
cards.add(new SetCardInfo("Swamp Mosquito", 31, Rarity.COMMON, SwampMosquito.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Thawing Glaciers", 189, Rarity.RARE, mage.cards.t.ThawingGlaciers.class));
cards.add(new SetCardInfo("Thought Lash", 58, Rarity.RARE, mage.cards.t.ThoughtLash.class));
cards.add(new SetCardInfo("Tidal Control", 59, Rarity.RARE, mage.cards.t.TidalControl.class));
cards.add(new SetCardInfo("Tornado", 86, Rarity.RARE, mage.cards.t.Tornado.class));
cards.add(new SetCardInfo("Unlikely Alliance", 153, Rarity.UNCOMMON, mage.cards.u.UnlikelyAlliance.class));
cards.add(new SetCardInfo("Varchild's War-Riders", 122, Rarity.RARE, mage.cards.v.VarchildsWarRiders.class));

View file

@ -89,6 +89,7 @@ public class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Aysen Bureaucrats", 105, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Aysen Crusader", 106, Rarity.RARE, mage.cards.a.AysenCrusader.class));
cards.add(new SetCardInfo("Aysen Highway", 107, Rarity.RARE, mage.cards.a.AysenHighway.class));
cards.add(new SetCardInfo("Baki's Curse", 27, Rarity.RARE, mage.cards.b.BakisCurse.class));
cards.add(new SetCardInfo("Baron Sengir", 1, Rarity.RARE, mage.cards.b.BaronSengir.class));
cards.add(new SetCardInfo("Black Carriage", 2, Rarity.RARE, mage.cards.b.BlackCarriage.class));
cards.add(new SetCardInfo("Carapace", 55, Rarity.COMMON, mage.cards.c.Carapace.class));

View file

@ -69,7 +69,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Adarkar Sentinel", 201, Rarity.COMMON, mage.cards.a.AdarkarSentinel.class));
cards.add(new SetCardInfo("Aeolipile", 202, Rarity.COMMON, mage.cards.a.Aeolipile.class));
cards.add(new SetCardInfo("Ambush Party", 115, Rarity.COMMON, mage.cards.a.AmbushParty.class));
cards.add(new SetCardInfo("An-Zerrin Ruins", 117, Rarity.RARE, mage.cards.a.AnZerrinRuins.class));
cards.add(new SetCardInfo("An-Zerrin Ruins", 117, Rarity.RARE, mage.cards.a.AnZerrinRuins.class));
cards.add(new SetCardInfo("Anarchy", 116, Rarity.RARE, mage.cards.a.Anarchy.class));
cards.add(new SetCardInfo("Angel of Fury", 2, Rarity.RARE, mage.cards.a.AngelOfFury.class));
cards.add(new SetCardInfo("Angel of Light", 3, Rarity.UNCOMMON, mage.cards.a.AngelOfLight.class));
@ -78,7 +78,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, ArmorThrull.class));
cards.add(new SetCardInfo("Aurochs", 153, Rarity.COMMON, mage.cards.a.Aurochs.class));
cards.add(new SetCardInfo("Aysen Bureaucrats", 6, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class));
cards.add(new SetCardInfo("Aysen Crusader", 7, Rarity.UNCOMMON, mage.cards.a.AysenCrusader.class));
cards.add(new SetCardInfo("Aysen Crusader", 7, Rarity.UNCOMMON, mage.cards.a.AysenCrusader.class));
cards.add(new SetCardInfo("Badlands", 225, Rarity.RARE, mage.cards.b.Badlands.class));
cards.add(new SetCardInfo("Balduvian Conjurer", 40, Rarity.COMMON, mage.cards.b.BalduvianConjurer.class));
cards.add(new SetCardInfo("Balduvian Dead", 79, Rarity.UNCOMMON, mage.cards.b.BalduvianDead.class));
@ -116,7 +116,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Elvish Hunter", 157, Rarity.COMMON, ElvishHunter.class));
cards.add(new SetCardInfo("Elvish Ranger", 158, Rarity.COMMON, mage.cards.e.ElvishRanger.class));
cards.add(new SetCardInfo("Elvish Spirit Guide", 159, Rarity.UNCOMMON, mage.cards.e.ElvishSpiritGuide.class));
cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class));
cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class));
cards.add(new SetCardInfo("Enervate", 47, Rarity.COMMON, mage.cards.e.Enervate.class));
cards.add(new SetCardInfo("Errantry", 124, Rarity.COMMON, mage.cards.e.Errantry.class));
cards.add(new SetCardInfo("Farrel's Mantle", 13, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class));
@ -171,6 +171,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Minion of Leshrac", 104, Rarity.RARE, mage.cards.m.MinionOfLeshrac.class));
cards.add(new SetCardInfo("Mudslide", 136, Rarity.RARE, mage.cards.m.Mudslide.class));
cards.add(new SetCardInfo("Narwhal", 57, Rarity.UNCOMMON, mage.cards.n.Narwhal.class));
cards.add(new SetCardInfo("Nature's Wrath", 172, Rarity.RARE, mage.cards.n.NaturesWrath.class));
cards.add(new SetCardInfo("Necrite", 106, Rarity.COMMON, Necrite.class));
cards.add(new SetCardInfo("Necropotence", 107, Rarity.RARE, mage.cards.n.Necropotence.class));
cards.add(new SetCardInfo("Night Soil", 173, Rarity.UNCOMMON, NightSoil.class));
@ -194,6 +195,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Reinforcements", 28, Rarity.COMMON, mage.cards.r.Reinforcements.class));
cards.add(new SetCardInfo("Reprisal", 29, Rarity.COMMON, mage.cards.r.Reprisal.class));
cards.add(new SetCardInfo("Righteous Fury", 30, Rarity.RARE, mage.cards.r.RighteousFury.class));
cards.add(new SetCardInfo("Ritual of Subdual", 174, Rarity.RARE, mage.cards.r.RitualOfSubdual.class));
cards.add(new SetCardInfo("Ritual of the Machine", 109, Rarity.RARE, mage.cards.r.RitualOfTheMachine.class));
cards.add(new SetCardInfo("Roterothopter", 218, Rarity.COMMON, mage.cards.r.Roterothopter.class));
cards.add(new SetCardInfo("Royal Trooper", 32, Rarity.COMMON, mage.cards.r.RoyalTrooper.class));
@ -250,4 +252,4 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Zuran Spellcaster", 76, Rarity.COMMON, mage.cards.z.ZuranSpellcaster.class));
}
}
}

View file

@ -224,6 +224,7 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Sandstorm", 164, Rarity.COMMON, mage.cards.s.Sandstorm.class));
cards.add(new SetCardInfo("Savannah", 250, Rarity.RARE, mage.cards.s.Savannah.class));
cards.add(new SetCardInfo("Savannah Lions", 24, Rarity.UNCOMMON, mage.cards.s.SavannahLions.class));
cards.add(new SetCardInfo("Scarwood Bandits", 165, Rarity.RARE, mage.cards.s.ScarwoodBandits.class));
cards.add(new SetCardInfo("Scavenger Folk", 166, Rarity.COMMON, mage.cards.s.ScavengerFolk.class));
cards.add(new SetCardInfo("Scavenging Ghoul", 95, Rarity.UNCOMMON, mage.cards.s.ScavengingGhoul.class));
cards.add(new SetCardInfo("Scrubland", 251, Rarity.RARE, mage.cards.s.Scrubland.class));
@ -277,7 +278,7 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Urza's Power Plant", 258, Rarity.LAND, mage.cards.u.UrzasPowerPlant.class));
cards.add(new SetCardInfo("Urza's Tower", 259, Rarity.LAND, mage.cards.u.UrzasTower.class));
cards.add(new SetCardInfo("Veteran Bodyguard", 32, Rarity.RARE, mage.cards.v.VeteranBodyguard.class));
cards.add(new SetCardInfo("Vibrating Sphere", 238, Rarity.RARE, mage.cards.v.VibratingSphere.class));
cards.add(new SetCardInfo("Vibrating Sphere", 238, Rarity.RARE, mage.cards.v.VibratingSphere.class));
cards.add(new SetCardInfo("Volcanic Island", 260, Rarity.RARE, mage.cards.v.VolcanicIsland.class));
cards.add(new SetCardInfo("War Mammoth", 172, Rarity.COMMON, mage.cards.w.WarMammoth.class));
cards.add(new SetCardInfo("Warp Artifact", 100, Rarity.COMMON, mage.cards.w.WarpArtifact.class));
@ -296,4 +297,4 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Zombie Master", 105, Rarity.UNCOMMON, mage.cards.z.ZombieMaster.class));
}
}
}

View file

@ -154,6 +154,7 @@ public class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Gravebane Zombie", 25, Rarity.COMMON, mage.cards.g.GravebaneZombie.class));
cards.add(new SetCardInfo("Grave Servitude", 24, Rarity.COMMON, mage.cards.g.GraveServitude.class));
cards.add(new SetCardInfo("Grinning Totem", 268, Rarity.RARE, mage.cards.g.GrinningTotem.class));
cards.add(new SetCardInfo("Hakim, Loreweaver", 68, Rarity.RARE, mage.cards.h.HakimLoreweaver.class));
cards.add(new SetCardInfo("Hall of Gemstone", 119, Rarity.RARE, mage.cards.h.HallOfGemstone.class));
cards.add(new SetCardInfo("Hammer of Bogardan", 181, Rarity.RARE, mage.cards.h.HammerOfBogardan.class));
cards.add(new SetCardInfo("Harbinger of Night", 26, Rarity.RARE, mage.cards.h.HarbingerOfNight.class));

View file

@ -150,7 +150,7 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Fertile Ground", 252, Rarity.COMMON, mage.cards.f.FertileGround.class));
cards.add(new SetCardInfo("Fiery Mantle", 186, Rarity.COMMON, mage.cards.f.FieryMantle.class));
cards.add(new SetCardInfo("Fire Ants", 187, Rarity.UNCOMMON, mage.cards.f.FireAnts.class));
cards.add(new SetCardInfo("Flesh Reaver", 136, Rarity.UNCOMMON, mage.cards.f.FleshReaver.class));
cards.add(new SetCardInfo("Flesh Reaver", 136, Rarity.UNCOMMON, mage.cards.f.FleshReaver.class));
cards.add(new SetCardInfo("Fluctuator", 295, Rarity.RARE, mage.cards.f.Fluctuator.class));
cards.add(new SetCardInfo("Fog Bank", 75, Rarity.UNCOMMON, mage.cards.f.FogBank.class));
cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
@ -261,15 +261,17 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Rain of Salt", 206, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class));
cards.add(new SetCardInfo("Ravenous Skirge", 152, Rarity.COMMON, mage.cards.r.RavenousSkirge.class));
cards.add(new SetCardInfo("Raze", 207, Rarity.COMMON, mage.cards.r.Raze.class));
cards.add(new SetCardInfo("Recantation", 91, Rarity.RARE, mage.cards.r.Recantation.class));
cards.add(new SetCardInfo("Redeem", 33, Rarity.UNCOMMON, mage.cards.r.Redeem.class));
cards.add(new SetCardInfo("Reflexes", 208, Rarity.COMMON, mage.cards.r.Reflexes.class));
cards.add(new SetCardInfo("Rejuvenate", 271, Rarity.COMMON, mage.cards.r.Rejuvenate.class));
cards.add(new SetCardInfo("Remembrance", 34, Rarity.RARE, mage.cards.r.Remembrance.class));
cards.add(new SetCardInfo("Remembrance", 34, Rarity.RARE, mage.cards.r.Remembrance.class));
cards.add(new SetCardInfo("Remote Isle", 324, Rarity.COMMON, mage.cards.r.RemoteIsle.class));
cards.add(new SetCardInfo("Reprocess", 154, Rarity.RARE, mage.cards.r.Reprocess.class));
cards.add(new SetCardInfo("Rescind", 92, Rarity.COMMON, mage.cards.r.Rescind.class));
cards.add(new SetCardInfo("Retaliation", 272, Rarity.UNCOMMON, mage.cards.r.Retaliation.class));
cards.add(new SetCardInfo("Rewind", 93, Rarity.COMMON, mage.cards.r.Rewind.class));
cards.add(new SetCardInfo("Rumbling Crescendo", 210, Rarity.RARE, mage.cards.r.RumblingCrescendo.class));
cards.add(new SetCardInfo("Rune of Protection: Artifacts", 35, Rarity.UNCOMMON, mage.cards.r.RuneOfProtectionArtifacts.class));
cards.add(new SetCardInfo("Rune of Protection: Black", 36, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlack.class));
cards.add(new SetCardInfo("Rune of Protection: Blue", 37, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlue.class));
@ -288,6 +290,7 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Seasoned Marshal", 44, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class));
cards.add(new SetCardInfo("Serra Avatar", 45, Rarity.RARE, mage.cards.s.SerraAvatar.class));
cards.add(new SetCardInfo("Serra's Embrace", 47, Rarity.UNCOMMON, mage.cards.s.SerrasEmbrace.class));
cards.add(new SetCardInfo("Serra's Liturgy", 49, Rarity.RARE, mage.cards.s.SerrasLiturgy.class));
cards.add(new SetCardInfo("Serra's Sanctum", 325, Rarity.RARE, mage.cards.s.SerrasSanctum.class));
cards.add(new SetCardInfo("Serra Zealot", 46, Rarity.COMMON, mage.cards.s.SerraZealot.class));
cards.add(new SetCardInfo("Shimmering Barrier", 50, Rarity.UNCOMMON, mage.cards.s.ShimmeringBarrier.class));
@ -306,7 +309,7 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Smokestack", 309, Rarity.RARE, mage.cards.s.Smokestack.class));
cards.add(new SetCardInfo("Smoldering Crater", 328, Rarity.COMMON, mage.cards.s.SmolderingCrater.class));
cards.add(new SetCardInfo("Sneak Attack", 218, Rarity.RARE, mage.cards.s.SneakAttack.class));
cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class));
cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class));
cards.add(new SetCardInfo("Spined Fluke", 160, Rarity.UNCOMMON, mage.cards.s.SpinedFluke.class));
cards.add(new SetCardInfo("Spire Owl", 98, Rarity.COMMON, mage.cards.s.SpireOwl.class));
cards.add(new SetCardInfo("Spreading Algae", 274, Rarity.UNCOMMON, mage.cards.s.SpreadingAlgae.class));
@ -338,7 +341,7 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Unworthy Dead", 163, Rarity.COMMON, mage.cards.u.UnworthyDead.class));
cards.add(new SetCardInfo("Urza's Armor", 313, Rarity.UNCOMMON, mage.cards.u.UrzasArmor.class));
cards.add(new SetCardInfo("Vampiric Embrace", 164, Rarity.UNCOMMON, mage.cards.v.VampiricEmbrace.class));
cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class));
cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class));
cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class));
cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class));
cards.add(new SetCardInfo("Viashino Runner", 224, Rarity.COMMON, mage.cards.v.ViashinoRunner.class));
@ -350,6 +353,8 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Voice of Law", 55, Rarity.UNCOMMON, mage.cards.v.VoiceOfLaw.class));
cards.add(new SetCardInfo("Voltaic Key", 314, Rarity.UNCOMMON, mage.cards.v.VoltaicKey.class));
cards.add(new SetCardInfo("Vug Lizard", 227, Rarity.UNCOMMON, mage.cards.v.VugLizard.class));
cards.add(new SetCardInfo("War Dance", 282, Rarity.UNCOMMON, mage.cards.w.WarDance.class));
cards.add(new SetCardInfo("Wall of Junk", 315, Rarity.UNCOMMON, mage.cards.w.WallOfJunk.class));
cards.add(new SetCardInfo("Western Paladin", 168, Rarity.RARE, mage.cards.w.WesternPaladin.class));
cards.add(new SetCardInfo("Whetstone", 316, Rarity.RARE, mage.cards.w.Whetstone.class));
cards.add(new SetCardInfo("Whirlwind", 283, Rarity.RARE, mage.cards.w.Whirlwind.class));

View file

@ -35,16 +35,19 @@ public class HopeOfGhirapurTest extends CardTestPlayerBase {
// from the battlefield and returned back.
@Test
public void testWhenHopeOfGhirapurWasRemovedAndReturnedBack() {
// Flying
// Sacrifice Hope of Ghirapur: Until your next turn, target player who was dealt combat damage by Hope of Ghirapur this turn can't cast noncreature spells.
addCard(Zone.BATTLEFIELD, playerA, "Hope of Ghirapur");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
// Exile target creature you control, then return that card to the battlefield under your control.
addCard(Zone.HAND, playerA, "Cloudshift");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Shock");
attack(1, playerA, "Hope of Ghirapur");
castSpell(1, PhaseStep.END_COMBAT, playerA, "Cloudshift", "Hope of Ghirapur");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sacrifice", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cloudshift", "Hope of Ghirapur");
activateAbility(1, PhaseStep.END_TURN, playerA, "Sacrifice", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Shock", playerA);

View file

@ -40,6 +40,7 @@ import mage.abilities.effects.Effects;
import mage.constants.AbilityType;
import mage.constants.AbilityWord;
import mage.constants.EffectType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone;
import mage.game.Controllable;
import mage.game.Game;
@ -539,4 +540,8 @@ public interface Ability extends Controllable, Serializable {
void setCanFizzle(boolean canFizzle);
boolean canFizzle();
void setTargetAdjustment(TargetAdjustment targetAdjustment);
TargetAdjustment getTargetAdjustment();
}

View file

@ -99,6 +99,7 @@ public abstract class AbilityImpl implements Ability {
protected List<Watcher> watchers = null;
protected List<Ability> subAbilities = null;
protected boolean canFizzle = true;
protected TargetAdjustment targetAdjustment = TargetAdjustment.NONE;
public AbilityImpl(AbilityType abilityType, Zone zone) {
this.id = UUID.randomUUID();
@ -147,6 +148,7 @@ public abstract class AbilityImpl implements Ability {
this.sourceObject = ability.sourceObject;
this.sourceObjectZoneChangeCounter = ability.sourceObjectZoneChangeCounter;
this.canFizzle = ability.canFizzle;
this.targetAdjustment = ability.targetAdjustment;
}
@Override
@ -1233,4 +1235,13 @@ public abstract class AbilityImpl implements Ability {
this.canFizzle = canFizzle;
}
@Override
public void setTargetAdjustment(TargetAdjustment targetAdjustment) {
this.targetAdjustment = targetAdjustment;
}
@Override
public TargetAdjustment getTargetAdjustment() {
return targetAdjustment;
}
}

View file

@ -71,6 +71,6 @@ public class ConditionalActivatedAbility extends ActivatedAbilityImpl {
if (ruleText != null && !ruleText.isEmpty()) {
return ruleText;
}
return super.getRule() + " Activate this ability only " + condition.toString();
return super.getRule() + " Activate this ability only " + condition.toString() + ".";
}
}

View file

@ -37,17 +37,32 @@ import mage.MageObjectImpl;
import mage.Mana;
import mage.ObjectColor;
import mage.abilities.*;
import mage.abilities.effects.common.NameACardEffect;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.repository.PluginClassloaderRegistery;
import mage.constants.*;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.counters.Counters;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.*;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInOpponentsGraveyard;
import mage.target.common.TargetCreaturePermanent;
import mage.util.GameLog;
import mage.util.SubTypeList;
import mage.watchers.Watcher;
@ -317,6 +332,94 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
return spellAbility;
}
// @Override
// public void adjustCosts(Ability ability, Game game) {
// }
@Override
public void adjustTargets(Ability ability, Game game) {
int xValue;
TargetPermanent oldTargetPermanent;
FilterPermanent permanentFilter;
int minTargets;
int maxTargets;
switch (ability.getTargetAdjustment()) {
case NONE:
break;
case X_CMC_EQUAL_PERM:
xValue = ability.getManaCostsToPay().getX();
oldTargetPermanent = (TargetPermanent) ability.getTargets().get(0);
minTargets = oldTargetPermanent.getMinNumberOfTargets();
maxTargets = oldTargetPermanent.getMaxNumberOfTargets();
permanentFilter = oldTargetPermanent.getFilter().copy();
permanentFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
ability.getTargets().clear();
ability.getTargets().add(new TargetPermanent(minTargets, maxTargets, permanentFilter, false));
break;
case X_TARGETS:
xValue = ability.getManaCostsToPay().getX();
permanentFilter = ((TargetPermanent) ability.getTargets().get(0)).getFilter();
ability.getTargets().clear();
ability.addTarget(new TargetPermanent(xValue, permanentFilter));
break;
case X_POWER_LEQ:// Minamo Sightbender only
xValue = ability.getManaCostsToPay().getX();
oldTargetPermanent = (TargetPermanent) ability.getTargets().get(0);
minTargets = oldTargetPermanent.getMinNumberOfTargets();
maxTargets = oldTargetPermanent.getMaxNumberOfTargets();
permanentFilter = oldTargetPermanent.getFilter().copy();
permanentFilter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1));
ability.getTargets().clear();
ability.getTargets().add(new TargetPermanent(minTargets, maxTargets, permanentFilter, false));
break;
case VERSE_COUNTER_TARGETS:
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId());
if (sourcePermanent != null) {
xValue = sourcePermanent.getCounters(game).getCount(CounterType.VERSE);
permanentFilter = ((TargetPermanent) ability.getTargets().get(0)).getFilter();
ability.getTargets().clear();
ability.addTarget(new TargetPermanent(0, xValue, permanentFilter, false));
}
break;
case X_CMC_EQUAL_GY_CARD: //Geth, Lord of the Vault only
xValue = ability.getManaCostsToPay().getX();
TargetCard oldTarget = (TargetCard) ability.getTargets().get(0);
FilterCard filterCard = oldTarget.getFilter().copy();
filterCard.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
ability.getTargets().clear();
ability.getTargets().add(new TargetCardInOpponentsGraveyard(filterCard));
break;
case CHOSEN_NAME: //Declaration of Naught only
ability.getTargets().clear();
FilterSpell filterSpell = new FilterSpell("spell with the chosen name");
filterSpell.add(new NamePredicate((String) game.getState().getValue(ability.getSourceId().toString() + NameACardEffect.INFO_KEY)));
TargetSpell target = new TargetSpell(1, filterSpell);
ability.addTarget(target);
break;
case CHOSEN_COLOR: //Pentarch Paladin only
ObjectColor chosenColor = (ObjectColor) game.getState().getValue(ability.getSourceId() + "_color");
ability.getTargets().clear();
FilterPermanent filter = new FilterPermanent("permanent of the chosen color.");
if (chosenColor != null) {
filter.add(new ColorPredicate(chosenColor));
} else {
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, -5));// Pretty sure this is always false
}
oldTargetPermanent = new TargetPermanent(filter);
ability.addTarget(oldTargetPermanent);
break;
case TREASURE_COUNTER_POWER: //Legacy's Allure only
sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId());
if (sourcePermanent != null) {
xValue = sourcePermanent.getCounters(game).getCount(CounterType.TREASURE);
FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creature with power less than or equal to the number of treasure counters on {this}");
filter2.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1));
ability.getTargets().clear();
ability.getTargets().add(new TargetCreaturePermanent(filter2));
}
break;
}
}
@Override
public void setOwnerId(UUID ownerId) {
this.ownerId = ownerId;

View file

@ -0,0 +1,16 @@
package mage.constants;
/**
*
* @author TheElk801
*/
public enum TargetAdjustment {
NONE,
X_TARGETS,
X_CMC_EQUAL_PERM,
X_CMC_EQUAL_GY_CARD,
X_POWER_LEQ, CHOSEN_NAME,
CHOSEN_COLOR,
VERSE_COUNTER_TARGETS,
TREASURE_COUNTER_POWER
}

View file

@ -122,6 +122,7 @@ public enum CounterType {
TIME("time"),
TOWER("tower"),
TRAP("trap"),
TREASURE("treasure"),
UNITY("unity"),
VELOCITY("velocity"),
VERSE("verse"),

View file

@ -0,0 +1,50 @@
/*
* 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.filter.predicate.permanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author North
*/
public class DefendingPlayerControlsPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Permanent>> {
@Override
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
return input.getObject().getControllerId().equals(game.getCombat().getDefenderId(input.getSourceId()));
}
@Override
public String toString() {
return "Another";
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.filter.predicate.permanent;
import mage.cards.Card;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
/**
*
* @author North
*/
public class DefendingPlayerOwnsCardPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Card>> {
@Override
public boolean apply(ObjectSourcePlayer<Card> input, Game game) {
return input.getObject().getOwnerId().equals(game.getCombat().getDefenderId(input.getSourceId()));
}
@Override
public String toString() {
return "Another";
}
}

View file

@ -74,6 +74,7 @@ public class StackAbility extends StackObjImpl implements Ability {
private UUID controllerId;
private String name;
private String expansionSetCode;
private TargetAdjustment targetAdjustment = TargetAdjustment.NONE;
public StackAbility(Ability ability, UUID controllerId) {
this.ability = ability;
@ -86,6 +87,7 @@ public class StackAbility extends StackObjImpl implements Ability {
this.controllerId = stackAbility.controllerId;
this.name = stackAbility.name;
this.expansionSetCode = stackAbility.expansionSetCode;
this.targetAdjustment = stackAbility.targetAdjustment;
}
@Override
@ -537,7 +539,7 @@ public class StackAbility extends StackObjImpl implements Ability {
@Override
public int getSourceObjectZoneChangeCounter() {
throw new UnsupportedOperationException("Not supported.");
return ability.getSourceObjectZoneChangeCounter();
}
@Override
@ -612,4 +614,13 @@ public class StackAbility extends StackObjImpl implements Ability {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setTargetAdjustment(TargetAdjustment targetAdjustment) {
this.targetAdjustment = targetAdjustment;
}
@Override
public TargetAdjustment getTargetAdjustment() {
return targetAdjustment;
}
}

View file

@ -53,8 +53,7 @@ public interface Target extends Serializable {
boolean isNotTarget();
/**
* controls if it will be checked, if the target can be targeted from
* source
* controls if it will be checked, if the target can be targeted from source
*
* @param notTarget true = do not check for protection, false = check for
* protection
@ -113,6 +112,8 @@ public interface Target extends Serializable {
int getNumberOfTargets();
int getMinNumberOfTargets();
int getMaxNumberOfTargets();
void setMinNumberOfTargets(int minNumberofTargets);
@ -157,8 +158,8 @@ public interface Target extends Serializable {
void setTargetTag(int tag);
Target getOriginalTarget();
// used for cards like Spellskite
void setTargetAmount(UUID targetId, int amount, Game game);
}

View file

@ -105,6 +105,11 @@ public abstract class TargetImpl implements Target {
return this.minNumberOfTargets;
}
@Override
public int getMinNumberOfTargets() {
return this.minNumberOfTargets;
}
@Override
public int getMaxNumberOfTargets() {
return this.maxNumberOfTargets;