Merge origin/master

This commit is contained in:
fireshoes 2015-08-17 09:17:10 -05:00
commit 17c45110a9
67 changed files with 2059 additions and 487 deletions

View file

@ -43,6 +43,7 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
@ -56,10 +57,6 @@ public class SlaveOfBolas extends CardImpl {
super(ownerId, 136, "Slave of Bolas", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{3}{U/R}{B}");
this.expansionSetCode = "ARB";
// Gain control of target creature. Untap that creature. It gains haste until end of turn. Sacrifice it at the beginning of the next end step.
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addEffect(new UntapTargetEffect());
@ -96,13 +93,17 @@ class SlaveOfBolasEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this");
sacrificeEffect.setTargetPointer(new FixedTarget(source.getFirstTarget()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
}

View file

@ -37,16 +37,13 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.Target;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.SecondTargetPointer;
/**
*
@ -65,15 +62,13 @@ public class LordOfTresserhorn extends CardImpl {
// When Lord of Tresserhorn enters the battlefield, you lose 2 life, you sacrifice two creatures, and target opponent draws two cards.
Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeSourceControllerEffect(2), false);
ability.addEffect(new SacrificeTargetEffect(", you sacrifice two creatures"));
Target target = new TargetControlledCreaturePermanent(2,2, new FilterControlledCreaturePermanent(), true);
ability.addTarget(target);
ability.addEffect(new SacrificeControllerEffect(new FilterControlledCreaturePermanent("creatures"), 2, "you"));
Effect effect = new DrawCardTargetEffect(2);
effect.setText(", and target opponent draws two cards");
effect.setTargetPointer(new SecondTargetPointer());
ability.addEffect(effect);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
// {B}: Regenerate Lord of Tresserhorn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}")));
}

View file

@ -33,7 +33,7 @@ import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
@ -54,10 +54,8 @@ public class PhyrexianWarBeast1 extends CardImpl {
this.toughness = new MageInt(4);
// When Phyrexian War Beast leaves the battlefield, sacrifice a land and Phyrexian War Beast deals 1 damage to you.
Effect effect = new SacrificeTargetEffect();
effect.setText("sacrifice a land");
Ability ability = new LeavesBattlefieldTriggeredAbility(effect, false);
effect = new DamageControllerEffect(1);
Ability ability = new LeavesBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterControlledLandPermanent(), 1, ""), false);
Effect effect = new DamageControllerEffect(1);
effect.setText("and {this} deals 1 damage to you");
ability.addEffect(effect);
ability.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent()));

View file

@ -28,9 +28,6 @@
package mage.sets.avacynrestored;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@ -40,7 +37,11 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.Token;
import mage.target.targetpointer.FixedTarget;
@ -54,7 +55,6 @@ public class ThatcherRevolt extends CardImpl {
super(ownerId, 158, "Thatcher Revolt", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{R}");
this.expansionSetCode = "AVR";
// Put three 1/1 red Human creature tokens with haste onto the battlefield. Sacrifice those tokens at the beginning of the next end step.
this.getSpellAbility().addEffect(new ThatcherRevoltEffect());
}
@ -90,14 +90,16 @@ class ThatcherRevoltEffect extends OneShotEffect {
for (int i = 0; i < 3; i++) {
RedHumanToken token = new RedHumanToken();
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this token");
sacrificeEffect.setTargetPointer(new FixedTarget(token.getLastAddedToken()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
Permanent permanent = game.getPermanent(token.getLastAddedToken());
if (permanent != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this token", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
}
return true;
}

View file

@ -25,13 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.championsofkamigawa;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -41,8 +37,10 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
@ -77,37 +75,36 @@ public class JunkyoBell extends CardImpl {
return new JunkyoBell(this);
}
private class JunkyoBellSacrificeEffect extends OneShotEffect {
private class JunkyoBellSacrificeEffect extends OneShotEffect {
public JunkyoBellSacrificeEffect() {
super(Outcome.Sacrifice);
this.staticText = "If you do, sacrifice that creature at the beginning of the next end step";
}
public JunkyoBellSacrificeEffect(final JunkyoBellSacrificeEffect effect) {
super(effect);
}
@Override
public JunkyoBellSacrificeEffect copy() {
return new JunkyoBellSacrificeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice boosted " + creature.getName());
sacrificeEffect.setTargetPointer(new FixedTarget(source.getFirstTarget()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
public JunkyoBellSacrificeEffect() {
super(Outcome.Sacrifice);
this.staticText = "If you do, sacrifice that creature at the beginning of the next end step";
}
public JunkyoBellSacrificeEffect(final JunkyoBellSacrificeEffect effect) {
super(effect);
}
@Override
public JunkyoBellSacrificeEffect copy() {
return new JunkyoBellSacrificeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice boosted " + creature.getName(), source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(creature, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
return false;
}
}
}

View file

@ -28,10 +28,6 @@
package mage.sets.championsofkamigawa;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
@ -42,7 +38,10 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SupertypePredicate;
@ -124,8 +123,7 @@ class KikiJikiMirrorBreakerEffect extends OneShotEffect {
token.addAbility(HasteAbility.getInstance());
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect();
sacrificeEffect.setText("Sacrifice the token at the beginning of the next end step");
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("Sacrifice the token at the beginning of the next end step", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(token.getLastAddedToken()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());

View file

@ -30,22 +30,26 @@ package mage.sets.championsofkamigawa;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.SetCardSubtypeAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
@ -54,7 +58,8 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class OniPossession extends CardImpl {
private static final List<String> setSubtypes = new ArrayList<String>();
private static final List<String> setSubtypes = new ArrayList<>();
static {
setSubtypes.add("Demon");
setSubtypes.add("Spirit");
@ -67,13 +72,14 @@ public class OniPossession extends CardImpl {
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// At the beginning of your upkeep, sacrifice a creature.
Ability ability2 = new BeginningOfUpkeepTriggeredAbility(new SacrificeTargetEffect("sacrifice a creature"), TargetController.YOU, false);
ability2.addTarget(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent(),false));
Ability ability2 = new BeginningOfUpkeepTriggeredAbility(
new SacrificeControllerEffect(new FilterControlledCreaturePermanent(), 1, ""), TargetController.YOU, false);
this.addAbility(ability2);
// Enchanted creature gets +3/+3 and has trample.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));

View file

@ -63,7 +63,6 @@ public class ThroughTheBreach extends CardImpl {
this.expansionSetCode = "CHK";
this.subtype.add("Arcane");
// You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice that creature at the beginning of the next end step.
this.getSpellAbility().addEffect(new ThroughTheBreachEffect());
// Splice onto Arcane {2}{R}{R}
@ -111,10 +110,10 @@ class ThroughTheBreachEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName());
sacrificeEffect.setTargetPointer(new FixedTarget(card.getId()));
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName(), source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());

View file

@ -0,0 +1,85 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.coldsnap;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author LoneFox
*/
public class LovisaColdeyes extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control that's a Barbarian, a Warrior, or a Berserker");
static {
filter.add(Predicates.or(new SubtypePredicate("Barbarian"), new SubtypePredicate("Warrior"), new SubtypePredicate("Berserker")));
}
public LovisaColdeyes(UUID ownerId) {
super(ownerId, 90, "Lovisa Coldeyes", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.expansionSetCode = "CSP";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Each creature you control that's a Barbarian, a Warrior, or a Berserker gets +2/+2 and has haste.
Effect effect = new BoostControlledEffect(2, 2, Duration.WhileOnBattlefield, filter, false);
effect.setText("Each creature you control that's a Barbarian, a Warrior, or a Berserker gets +2/+2");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
effect = new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false);
effect.setText("and has haste");
ability.addEffect(effect);
this.addAbility(ability);
}
public LovisaColdeyes(final LovisaColdeyes card) {
super(card);
}
@Override
public LovisaColdeyes copy() {
return new LovisaColdeyes(this);
}
}

View file

@ -28,9 +28,11 @@
package mage.sets.commander2013;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.CreateTokenTargetEffect;
import mage.abilities.keyword.EnchantAbility;
@ -44,6 +46,7 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.ZombieToken;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.targetpointer.FixedTarget;
@ -59,7 +62,6 @@ public class CurseOfShallowGraves extends CardImpl {
this.subtype.add("Aura");
this.subtype.add("Curse");
// Enchant player
TargetPlayer auraTarget = new TargetPlayer();
this.getSpellAbility().addTarget(auraTarget);
@ -83,7 +85,7 @@ public class CurseOfShallowGraves extends CardImpl {
class CurseOfShallowTriggeredAbility extends TriggeredAbilityImpl {
public CurseOfShallowTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenTargetEffect(new ZombieToken(), new StaticValue(1), true, false), true);
super(Zone.BATTLEFIELD, new CurseOfShallowEffect());
}
public CurseOfShallowTriggeredAbility(Effect effect, boolean optional, String text) {
@ -105,7 +107,7 @@ class CurseOfShallowTriggeredAbility extends TriggeredAbilityImpl {
if (enchantment != null
&& enchantment.getAttachedTo() != null
&& game.getCombat().getPlayerDefenders(game).contains(enchantment.getAttachedTo())) {
for (Effect effect: this.getEffects()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackerId()));
}
return true;
@ -124,3 +126,31 @@ class CurseOfShallowTriggeredAbility extends TriggeredAbilityImpl {
}
}
class CurseOfShallowEffect extends OneShotEffect {
public CurseOfShallowEffect() {
super(Outcome.Benefit);
this.staticText = "that attacking player may put a 2/2 black Zombie creature token onto the battlefield tapped";
}
public CurseOfShallowEffect(final CurseOfShallowEffect effect) {
super(effect);
}
@Override
public CurseOfShallowEffect copy() {
return new CurseOfShallowEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player attacker = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (attacker != null && attacker.chooseUse(outcome, "Put a 2/2 black Zombie creature token onto the battlefield tapped?", source, game)) {
Effect effect = new CreateTokenTargetEffect(new ZombieToken(), new StaticValue(1), true, false);
effect.setTargetPointer(targetPointer);
return effect.apply(game, source);
}
return false;
}
}

View file

@ -46,6 +46,7 @@ import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.EmptyToken;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
@ -113,15 +114,16 @@ class FeldonOfTheThirdPathEffect extends OneShotEffect {
}
token.addAbility(HasteAbility.getInstance());
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect();
sacrificeEffect.setText("Sacrifice the token at the beginning of the next end step");
sacrificeEffect.setTargetPointer(new FixedTarget(token.getLastAddedToken()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
Permanent permanent = game.getPermanent(token.getLastAddedToken());
if (permanent != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("Sacrifice the token at the beginning of the next end step", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
return true;
}

View file

@ -33,7 +33,6 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -64,7 +63,6 @@ public class WakeTheDead extends CardImpl {
super(ownerId, 31, "Wake the Dead", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{B}{B}");
this.expansionSetCode = "C14";
// Cast Wake the Dead only during combat on an opponent's turn.
Ability ability = new SimpleStaticAbility(Zone.ALL, new WakeTheDeadEffect());
ability.setRuleAtTheTop(true);
@ -72,7 +70,7 @@ public class WakeTheDead extends CardImpl {
// Return X target creature cards from your graveyard to the battlefield. Sacrifice those creatures at the beginning of the next end step.
this.getSpellAbility().addEffect(new WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard")));
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard")));
}
@Override
@ -80,7 +78,7 @@ public class WakeTheDead extends CardImpl {
if (ability instanceof SpellAbility) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
ability.addTarget(new TargetCardInYourGraveyard(xValue,xValue, new FilterCreatureCard("creature cards from your graveyard")));
ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, new FilterCreatureCard("creature cards from your graveyard")));
}
}
@ -159,8 +157,8 @@ class WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect extends OneShotEff
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.changeControllerId(source.getControllerId(), game);
Effect effect = new SacrificeTargetEffect("Sacrifice those creatures at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(permanent.getId()));
Effect effect = new SacrificeTargetEffect("Sacrifice those creatures at the beginning of the next end step", source.getControllerId());
effect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());

View file

@ -25,21 +25,20 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.dragonsmaze;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
@ -51,18 +50,17 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author LevelX2
*/
public class UbulSarGatekeepers extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
private static final FilterCreaturePermanent targetFilter = new FilterCreaturePermanent("creature an opponent controls");
static {
filter.add(new SubtypePredicate("Gate"));
targetFilter.add(new ControllerPredicate(TargetController.OPPONENT));
}
public UbulSarGatekeepers (UUID ownerId) {
public UbulSarGatekeepers(UUID ownerId) {
super(ownerId, 30, "Ubul Sar Gatekeepers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.expansionSetCode = "DGM";
this.subtype.add("Zombie");
@ -73,7 +71,7 @@ public class UbulSarGatekeepers extends CardImpl {
// Whenever Ubul Sar Gatekeepers enters the battlefield, if you control two or more Gates, target creature an opponent controls gets -2/-2 until end of turn.
Ability ability = new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(2))),
new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)),
new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 1),
"Whenever {this} enters the battlefield, if you control two or more Gates, target creature an opponent controls gets -2/-2 until end of turn.");
Target target = new TargetCreaturePermanent(targetFilter);
@ -81,7 +79,7 @@ public class UbulSarGatekeepers extends CardImpl {
this.addAbility(ability);
}
public UbulSarGatekeepers (final UbulSarGatekeepers card) {
public UbulSarGatekeepers(final UbulSarGatekeepers card) {
super(card);
}

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eventide;
import java.util.UUID;
@ -51,19 +50,20 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class AshlingTheExtinguisher extends CardImpl {
public AshlingTheExtinguisher (UUID ownerId) {
public AshlingTheExtinguisher(UUID ownerId) {
super(ownerId, 33, "Ashling, the Extinguisher", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.expansionSetCode = "EVE";
this.supertype.add("Legendary");
this.subtype.add("Elemental");
this.subtype.add("Shaman");
// Whenever Ashling, the Extinguisher deals combat damage to a player, choose target creature that player controls. He or she sacrifices that creature.
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.addAbility(new AshlingTheExtinguisherTriggeredAbility());
}
public AshlingTheExtinguisher (final AshlingTheExtinguisher card) {
public AshlingTheExtinguisher(final AshlingTheExtinguisher card) {
super(card);
}
@ -75,6 +75,7 @@ public class AshlingTheExtinguisher extends CardImpl {
}
class AshlingTheExtinguisherTriggeredAbility extends TriggeredAbilityImpl {
public AshlingTheExtinguisherTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeTargetEffect());
this.addTarget(new TargetCreaturePermanent());

View file

@ -30,14 +30,12 @@ package mage.sets.invasion;
import java.util.UUID;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
/**
*

View file

@ -0,0 +1,78 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.judgment;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LoneFox
*/
public class JeskaWarriorAdept extends CardImpl {
public JeskaWarriorAdept(UUID ownerId) {
super(ownerId, 93, "Jeska, Warrior Adept", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.expansionSetCode = "JUD";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Barbarian");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// {tap}: Jeska, Warrior Adept deals 1 damage to target creature or player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost());
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public JeskaWarriorAdept(final JeskaWarriorAdept card) {
super(card);
}
@Override
public JeskaWarriorAdept copy() {
return new JeskaWarriorAdept(this);
}
}

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.sets.legends;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.common.RegenerateTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class HorrorOfHorrors extends CardImpl {
private static final FilterControlledPermanent filter1 = new FilterControlledPermanent("a Swamp");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("black creature");
static {
filter1.add(new SubtypePredicate("Swamp"));
filter2.add(new ColorPredicate(ObjectColor.BLACK));
}
public HorrorOfHorrors(UUID ownerId) {
super(ownerId, 20, "Horror of Horrors", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
this.expansionSetCode = "LEG";
// Sacrifice a Swamp: Regenerate target black creature.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(filter1)));
ability.addTarget(new TargetCreaturePermanent(filter2));
this.addAbility(ability);
}
public HorrorOfHorrors(final HorrorOfHorrors card) {
super(card);
}
@Override
public HorrorOfHorrors copy() {
return new HorrorOfHorrors(this);
}
}

View file

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

View file

@ -29,15 +29,12 @@ package mage.sets.legions;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledLandPermanent;
import mage.target.common.TargetControlledPermanent;
import mage.filter.common.FilterLandPermanent;
/**
*
@ -53,11 +50,7 @@ public class GoblinFirebug extends CardImpl {
this.toughness = new MageInt(2);
// When Goblin Firebug leaves the battlefield, sacrifice a land.
Effect effect = new SacrificeTargetEffect();
effect.setText("sacrifice a land");
Ability ability = new LeavesBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent()));
this.addAbility(ability);
this.addAbility(new LeavesBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterLandPermanent(), 1, ""), false));
}
public GoblinFirebug(final GoblinFirebug card) {

View file

@ -82,7 +82,6 @@ public class IncandescentSoulstoke extends CardImpl {
// Other Elemental creatures you control get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true)));
// {1}{R}, {T}: You may put an Elemental creature card from your hand onto the battlefield. That creature gains haste until end of turn. Sacrifice it at the beginning of the next end step.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new IncandescentSoulstokeEffect(), new ManaCostsImpl<>("{1}{R}"));
ability.addCost(new TapSourceCost());
@ -133,10 +132,10 @@ class IncandescentSoulstokeEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName());
sacrificeEffect.setTargetPointer(new FixedTarget(card.getId()));
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName(), source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());

View file

@ -30,14 +30,13 @@ package mage.sets.magic2014;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -50,7 +49,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
@ -60,6 +58,7 @@ import mage.target.common.TargetCreaturePermanent;
public class ShadowbornDemon extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Demon creature");
static {
filter.add(Predicates.not(new SubtypePredicate("Demon")));
}
@ -75,17 +74,14 @@ public class ShadowbornDemon extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Shadowborn Demon enters the battlefield, destroy target non-Demon creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(),false);
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), false);
Target target = new TargetCreaturePermanent(filter);
ability.addTarget(target);
this.addAbility(ability);
// At the beginning of your upkeep, if there are fewer than six creature cards in your graveyard, sacrifice a creature.
TriggeredAbility triggeredAbility = new BeginningOfUpkeepTriggeredAbility(new SacrificeTargetEffect(), TargetController.YOU, false);
target = new TargetControlledCreaturePermanent();
target.setNotTarget(false);
triggeredAbility.addTarget(target);
this.addAbility(new ConditionalTriggeredAbility(
triggeredAbility,
new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(new FilterCreaturePermanent(), 1, ""), TargetController.YOU, false),
new InvertCondition(new CreatureCardsInControllerGraveCondition(6)),
"At the beginning of your upkeep, if there are fewer than six creature cards in your graveyard, sacrifice a creature"));
@ -102,6 +98,7 @@ public class ShadowbornDemon extends CardImpl {
}
class CreatureCardsInControllerGraveCondition implements Condition {
private int value;
public CreatureCardsInControllerGraveCondition(int value) {
@ -111,9 +108,8 @@ class CreatureCardsInControllerGraveCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Player p = game.getPlayer(source.getControllerId());
if (p != null && p.getGraveyard().count(new FilterCreatureCard(), game) >= value)
{
return true;
if (p != null && p.getGraveyard().count(new FilterCreatureCard(), game) >= value) {
return true;
}
return false;
}

View file

@ -29,16 +29,13 @@ package mage.sets.masterseditioniv;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledLandPermanent;
import mage.target.common.TargetControlledPermanent;
import mage.filter.common.FilterLandPermanent;
/**
*
@ -57,11 +54,7 @@ public class FoulSpirit extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Foul Spirit enters the battlefield, sacrifice a land.
Effect effect = new SacrificeTargetEffect();
effect.setText("sacrifice a land");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent()));
this.addAbility(ability);
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterLandPermanent(), 1, ""), false));
}
public FoulSpirit(final FoulSpirit card) {

View file

@ -0,0 +1,75 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.nemesis;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.FadingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LoneFox
*/
public class AncientHydra extends CardImpl {
public AncientHydra(UUID ownerId) {
super(ownerId, 76, "Ancient Hydra", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.expansionSetCode = "NMS";
this.subtype.add("Hydra");
this.power = new MageInt(5);
this.toughness = new MageInt(1);
// Fading 5
this.addAbility(new FadingAbility(5, this));
// {1}, Remove a fade counter from Ancient Hydra: Ancient Hydra deals 1 damage to target creature or player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}"));
ability.addCost(new RemoveCountersSourceCost(CounterType.FADE.createInstance(1)));
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public AncientHydra(final AncientHydra card) {
super(card);
}
@Override
public AncientHydra copy() {
return new AncientHydra(this);
}
}

View file

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

View file

@ -93,20 +93,23 @@ class SpellskiteEffect extends OneShotEffect {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
MageObject sourceObject = game.getObject(source.getSourceId());
if (stackObject != null && sourceObject != null) {
Targets targets;
Targets targets = new Targets();
Ability sourceAbility;
MageObject oldTarget = null;
if (stackObject instanceof Spell) {
Spell spell = (Spell)stackObject;
Spell spell = (Spell) stackObject;
sourceAbility = spell.getSpellAbility();
targets = spell.getSpellAbility().getTargets();
} else if (stackObject instanceof StackAbility) {
StackAbility stackAbility = (StackAbility)stackObject;
StackAbility stackAbility = (StackAbility) stackObject;
sourceAbility = stackAbility;
targets = stackAbility.getTargets();
} else {
return false;
}
for (UUID modeId : sourceAbility.getModes().getSelectedModes()) {
sourceAbility.getModes().setActiveMode(modeId);
targets.addAll(sourceAbility.getTargets());
}
boolean twoTimesTarget = false;
if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
Target target = targets.get(0);
@ -118,22 +121,22 @@ class SpellskiteEffect extends OneShotEffect {
}
} else {
Player player = game.getPlayer(source.getControllerId());
for (Target target: targets) {
for (UUID targetId: target.getTargets()) {
for (Target target : targets) {
for (UUID targetId : target.getTargets()) {
MageObject object = game.getObject(targetId);
String name;
if (object == null) {
Player targetPlayer = game.getPlayer(targetId);
name = targetPlayer.getLogName();
} else {
name = object.getName();
name = object.getLogName();
}
if (!targetId.equals(source.getSourceId()) && target.getTargets().contains(source.getSourceId())) {
// you can't change this target to Spellskite because Spellskite is already another targetId of that target.
twoTimesTarget = true;
continue;
}
if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), source, game)) {
if (name != null && player.chooseUse(Outcome.Neutral, "Change target from " + name + " to " + sourceObject.getLogName() + "?", source, game)) {
if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
oldTarget = game.getObject(targets.getFirstTarget());
target.remove(targetId);
@ -146,12 +149,12 @@ class SpellskiteEffect extends OneShotEffect {
}
}
if (oldTarget != null) {
game.informPlayers(sourceObject.getLogName() + ": Changed target of " +stackObject.getLogName() + " from " + oldTarget.getLogName() + " to " + sourceObject.getLogName());
game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTarget.getLogName() + " to " + sourceObject.getLogName());
} else {
if (twoTimesTarget) {
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getName());
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName());
} else {
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getName());
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName());
}
}
return true;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,72 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.ninthedition;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LoneFox
*/
public class SanctumGuardian extends CardImpl {
public SanctumGuardian(UUID ownerId) {
super(ownerId, 40, "Sanctum Guardian", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.expansionSetCode = "9ED";
this.subtype.add("Human");
this.subtype.add("Cleric");
this.power = new MageInt(1);
this.toughness = new MageInt(4);
// Sacrifice Sanctum Guardian: The next time a source of your choice would deal damage to target creature or player this turn, prevent that damage.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventNextDamageFromChosenSourceToTargetEffect(Duration.EndOfTurn),
new SacrificeSourceCost());
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public SanctumGuardian(final SanctumGuardian card) {
super(card);
}
@Override
public SanctumGuardian copy() {
return new SanctumGuardian(this);
}
}

View file

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

View file

@ -57,7 +57,7 @@ public class Complicate extends CardImpl {
this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}{U}")));
// When you cycle Complicate, you may counter target spell unless its controller pays {1}.
Ability ability = new CycleTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)));
Ability ability = new CycleTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(1)), true);
ability.addTarget(new TargetSpell());
this.addAbility(ability);
}

View file

@ -56,7 +56,7 @@ public class DeathPulse extends CardImpl {
// Cycling {1}{B}{B}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{1}{B}{B}")));
// When you cycle Death Pulse, you may have target creature get -1/-1 until end of turn.
Ability ability = new CycleTriggeredAbility(new BoostTargetEffect(-1, -1, Duration.EndOfTurn));
Ability ability = new CycleTriggeredAbility(new BoostTargetEffect(-1, -1, Duration.EndOfTurn), true);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

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

View file

@ -0,0 +1,66 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.onslaught;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class Inspirit extends CardImpl {
public Inspirit(UUID ownerId) {
super(ownerId, 41, "Inspirit", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "ONS";
// Untap target creature. It gets +2/+4 until end of turn.
this.getSpellAbility().addEffect(new UntapTargetEffect());
Effect effect = new BoostTargetEffect(2, 4, Duration.EndOfTurn);
effect.setText("It gets +2/+4 until end of turn");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public Inspirit(final Inspirit card) {
super(card);
}
@Override
public Inspirit copy() {
return new Inspirit(this);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.onslaught;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.CycleTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.CyclingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class PrimalBoost extends CardImpl {
public PrimalBoost(UUID ownerId) {
super(ownerId, 277, "Primal Boost", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{G}");
this.expansionSetCode = "ONS";
// Target creature gets +4/+4 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(4, 4, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Cycling {2}{G}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}{G}")));
// When you cycle Primal Boost, you may have target creature get +1/+1 until end of turn.
Ability ability = new CycleTriggeredAbility(new BoostTargetEffect(1, 1, Duration.EndOfTurn), true);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public PrimalBoost(final PrimalBoost card) {
super(card);
}
@Override
public PrimalBoost copy() {
return new PrimalBoost(this);
}
}

View file

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

View file

@ -33,6 +33,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -61,7 +62,7 @@ public class SeasideHaven extends CardImpl {
// {tap}: Add {1} to your mana pool.
this.addAbility(new ColorlessManaAbility());
// {W}{U}, {tap}, Sacrifice a Bird: Draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, null, new ManaCostsImpl<>("{W}{U}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{W}{U}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);

View file

@ -0,0 +1,72 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.onslaught;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.CycleTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PreventDamageToTargetEffect;
import mage.abilities.keyword.CyclingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LoneFox
*/
public class SunfireBalm extends CardImpl {
public SunfireBalm(UUID ownerId) {
super(ownerId, 56, "Sunfire Balm", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "ONS";
// Prevent the next 4 damage that would be dealt to target creature or player this turn.
this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, 4));
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
// Cycling {1}{W}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{1}{W}")));
// When you cycle Sunfire Balm, you may prevent the next 1 damage that would be dealt to target creature or player this turn.
Ability ability = new CycleTriggeredAbility(new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), true);
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public SunfireBalm(final SunfireBalm card) {
super(card);
}
@Override
public SunfireBalm copy() {
return new SunfireBalm(this);
}
}

View file

@ -28,10 +28,6 @@
package mage.sets.planarchaos;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@ -43,7 +39,12 @@ import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
@ -57,7 +58,6 @@ public class FatalFrenzy extends CardImpl {
super(ownerId, 98, "Fatal Frenzy", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{R}");
this.expansionSetCode = "PLC";
// Until end of turn, target creature you control gains trample and gets +X/+0, where X is its power. Sacrifice it at the beginning of the next end step.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true));
@ -94,13 +94,16 @@ class FatalFrenzyEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this");
sacrificeEffect.setTargetPointer(new FixedTarget(source.getFirstTarget()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature != null) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(targetCreature, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
return true;
}
}

View file

@ -76,8 +76,7 @@ public class RealityAcid extends CardImpl {
this.addAbility(new VanishingSacrificeAbility());
// When Reality Acid leaves the battlefield, enchanted permanent's controller sacrifices it.
Effect effect = new SacrificeTargetEffect();
effect.setText("enchanted permanent's controller sacrifices it");
Effect effect = new SacrificeTargetEffect("enchanted permanent's controller sacrifices it");
this.addAbility(new RealityAcidTriggeredAbility(effect, false));
}

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.sets.prophecy;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class WhipSergeant extends CardImpl {
public WhipSergeant(UUID ownerId) {
super(ownerId, 107, "Whip Sergeant", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.expansionSetCode = "PCY";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// {R}: Target creature gains haste until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{R}"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public WhipSergeant(final WhipSergeant card) {
super(card);
}
@Override
public WhipSergeant copy() {
return new WhipSergeant(this);
}
}

View file

@ -25,20 +25,25 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.riseoftheeldrazi;
import java.util.UUID;
import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
@ -48,29 +53,27 @@ import mage.target.common.TargetControlledCreaturePermanent;
*/
public class DemonicAppetite extends CardImpl {
public DemonicAppetite (UUID ownerId) {
public DemonicAppetite(UUID ownerId) {
super(ownerId, 106, "Demonic Appetite", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{B}");
this.expansionSetCode = "ROE";
this.subtype.add("Aura");
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature gets +3/+3.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
ability = new BeginningOfUpkeepTriggeredAbility(
new DemonicAppetiteEffect(),
TargetController.YOU,
false);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
// At the beginning of your upkeep, sacrifice a creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(new FilterCreaturePermanent("a creature"), 1, ""),
TargetController.YOU, false));
}
public DemonicAppetite (final DemonicAppetite card) {
public DemonicAppetite(final DemonicAppetite card) {
super(card);
}
@ -80,16 +83,16 @@ public class DemonicAppetite extends CardImpl {
}
}
class DemonicAppetiteEffect extends SacrificeTargetEffect {
class DemonicAppetiteEffect extends SacrificeTargetEffect {
DemonicAppetiteEffect() {
super();
staticText = "sacrifice a creature";
}
DemonicAppetiteEffect() {
super();
staticText = "sacrifice a creature";
}
@Override
public DemonicAppetiteEffect copy() {
return new DemonicAppetiteEffect();
}
@Override
public DemonicAppetiteEffect copy() {
return new DemonicAppetiteEffect();
}
}

View file

@ -32,15 +32,9 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.*;
@ -62,7 +56,6 @@ public class FootstepsOfTheGoryo extends CardImpl {
this.expansionSetCode = "SOK";
this.subtype.add("Arcane");
// Return target creature card from your graveyard to the battlefield. Sacrifice that creature at the beginning of the next end step.
this.getSpellAbility().addEffect(new FootstepsOfTheGoryoEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
@ -104,8 +97,8 @@ class FootstepsOfTheGoryoEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
// Sacrifice it at end of turn
Effect sacrificeEffect = new SacrificeTargetEffect("Sacrifice that creature at the beginning of next end step");
sacrificeEffect.setTargetPointer(new FixedTarget(card.getId()));
Effect sacrificeEffect = new SacrificeTargetEffect("Sacrifice that creature at the beginning of next end step", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());

View file

@ -30,23 +30,19 @@ package mage.sets.saviorsofkamigawa;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.dynamicvalue.common.TargetPermanentPowerCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -62,7 +58,10 @@ public class WineOfBloodAndIron extends CardImpl {
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true),
new GenericManaCost(4));
ability.addEffect(new WineOfBloodAndIronEffect());
Effect effect = new CreateDelayedTriggeredAbilityEffect(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()), false);
effect.setText("Sacrifice {this} at the beginning of the next end step");
ability.addEffect(effect);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
@ -76,32 +75,3 @@ public class WineOfBloodAndIron extends CardImpl {
return new WineOfBloodAndIron(this);
}
}
class WineOfBloodAndIronEffect extends OneShotEffect {
public WineOfBloodAndIronEffect() {
super(Outcome.Sacrifice);
this.staticText = "Sacrifice {this} at the beginning of the next end step";
}
public WineOfBloodAndIronEffect(final WineOfBloodAndIronEffect effect) {
super(effect);
}
@Override
public WineOfBloodAndIronEffect copy() {
return new WineOfBloodAndIronEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice this");
sacrificeEffect.setTargetPointer(new FixedTarget(source.getSourceId()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
}

View file

@ -25,13 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.scarsofmirrodin;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
@ -39,7 +35,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -60,16 +58,19 @@ public class ShapeAnew extends CardImpl {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
}
public ShapeAnew (UUID ownerId) {
public ShapeAnew(UUID ownerId) {
super(ownerId, 43, "Shape Anew", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{U}");
this.expansionSetCode = "SOM";
this.getSpellAbility().addEffect(new SacrificeTargetEffect());
// The controller of target artifact sacrifices it, then reveals cards from the top
// of his or her library until he or she reveals an artifact card. That player puts
// that card onto the battlefield, then shuffles all other cards revealed this way into his or her library.
this.getSpellAbility().addEffect(new SacrificeTargetEffect("The controller of target artifact sacrifices it"));
this.getSpellAbility().addTarget(new TargetPermanent(filter));
this.getSpellAbility().addEffect(new ShapeAnewEffect());
}
public ShapeAnew (final ShapeAnew card) {
public ShapeAnew(final ShapeAnew card) {
super(card);
}
@ -82,7 +83,7 @@ public class ShapeAnew extends CardImpl {
public ShapeAnewEffect() {
super(Outcome.PutCardInPlay);
staticText = "Then reveals cards from the top of his or her library until he or she reveals an artifact card. That player puts that card onto the battlefield, then shuffles all other cards revealed this way into his or her library";
staticText = ", then reveals cards from the top of his or her library until he or she reveals an artifact card. That player puts that card onto the battlefield, then shuffles all other cards revealed this way into his or her library";
}
public ShapeAnewEffect(ShapeAnewEffect effect) {
@ -102,9 +103,9 @@ public class ShapeAnew extends CardImpl {
Cards revealed = new CardsImpl();
Card artifactCard = null;
Cards nonArtifactCards = new CardsImpl();
Player player = game.getPlayer(sourcePermanent.getControllerId());
while (artifactCard == null && player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game);
Player targetController = game.getPlayer(sourcePermanent.getControllerId());
while (artifactCard == null && targetController.getLibrary().size() > 0) {
Card card = targetController.getLibrary().removeFromTop(game);
revealed.add(card);
if (card.getCardType().contains(CardType.ARTIFACT)) {
artifactCard = card;
@ -112,14 +113,12 @@ public class ShapeAnew extends CardImpl {
nonArtifactCards.add(card);
}
}
player.revealCards("Shape Anew", revealed, game);
targetController.revealCards(sourcePermanent.getIdName(), revealed, game);
if (artifactCard != null) {
artifactCard.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
artifactCard.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), targetController.getId());
}
for (Card cardToMove: nonArtifactCards.getCards(game)) {
cardToMove.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
player.shuffleLibrary(game);
targetController.moveCards(nonArtifactCards, null, Zone.LIBRARY, source, game);
targetController.shuffleLibrary(game);
return true;
}

View file

@ -52,6 +52,7 @@ import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
@ -117,16 +118,19 @@ class ImpromptuRaidEffect extends OneShotEffect {
return true;
}
if (controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId())) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect();
sacrificeEffect.setTargetPointer(new FixedTarget(card.getId()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("", source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
return true;
}
}

View file

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

View file

@ -31,12 +31,11 @@ import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.keyword.FearAbility;
import mage.cards.CardImpl;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
/**
*
@ -53,10 +52,12 @@ public class CommanderGrevenIlVec extends CardImpl {
this.power = new MageInt(7);
this.toughness = new MageInt(5);
Ability ability = new EntersBattlefieldTriggeredAbility(new SacrificeTargetEffect(), false);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
// Fear (This creature can't be blocked except by artifact creatures and/or black creatures.)
this.addAbility(FearAbility.getInstance());
// When Commander Greven il-Vec enters the battlefield, sacrifice a creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterCreaturePermanent(), 1, ""), false));
}
public CommanderGrevenIlVec(final CommanderGrevenIlVec card) {

View file

@ -0,0 +1,75 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.tempest;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
/**
*
* @author LoneFox
*/
public class MarbleTitan extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures with power 3 or greater");
static {
filter.add(new PowerPredicate(Filter.ComparisonType.GreaterThan, 2));
}
public MarbleTitan(UUID ownerId) {
super(ownerId, 240, "Marble Titan", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.expansionSetCode = "TMP";
this.subtype.add("Giant");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Creatures with power 3 or greater don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter)));
}
public MarbleTitan(final MarbleTitan card) {
super(card);
}
@Override
public MarbleTitan copy() {
return new MarbleTitan(this);
}
}

View file

@ -29,13 +29,12 @@ package mage.sets.tempest;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
/**
*
@ -51,9 +50,7 @@ public class ServantOfVolrath extends CardImpl {
this.toughness = new MageInt(3);
// When Servant of Volrath leaves the battlefield, sacrifice a creature.
Ability ability = new LeavesBattlefieldTriggeredAbility(new SacrificeTargetEffect(), false);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
this.addAbility(new LeavesBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterCreaturePermanent(), 1, ""), false));
}
public ServantOfVolrath(final ServantOfVolrath card) {

View file

@ -87,9 +87,9 @@ class BeaconOfImmortalityEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
int amount = game.getLife();
int amount = player.getLife();
if (amount < 0) {
player.loseLife(amount, game);
player.loseLife(-amount, game);
return true;
}
if (amount > 0) {

View file

@ -0,0 +1,69 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.urzassaga;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.CardsInHandCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
/**
*
* @author LoneFox
*/
public class ImaginaryPet extends CardImpl {
public ImaginaryPet(UUID ownerId) {
super(ownerId, 81, "Imaginary Pet", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.expansionSetCode = "USG";
this.subtype.add("Illusion");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// At the beginning of your upkeep, if you have a card in hand, return Imaginary Pet to its owner's hand.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new ReturnToHandSourceEffect(true), TargetController.YOU, false);
this.addAbility(new ConditionalTriggeredAbility(ability, new CardsInHandCondition(CardsInHandCondition.CountType.MORE_THAN, 0),
"At the beginning of your upkeep, if you have a card in hand, return {this} to its owner's hand."));
}
public ImaginaryPet(final ImaginaryPet card) {
super(card);
}
@Override
public ImaginaryPet copy() {
return new ImaginaryPet(this);
}
}

View file

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

View file

@ -62,7 +62,6 @@ public class SneakAttack extends CardImpl {
super(ownerId, 218, "Sneak Attack", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
this.expansionSetCode = "USG";
// {R}: You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice the creature at the beginning of the next end step.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SneakAttackEffect(), new ManaCostsImpl("{R}")));
}
@ -106,18 +105,19 @@ class SneakAttackEffect extends OneShotEffect {
if (card != null) {
if (player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) {
Permanent permanent = game.getPermanent(card.getId());
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName());
sacrificeEffect.setTargetPointer(new FixedTarget(card.getId()));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
if (permanent != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName(), source.getControllerId());
sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
return true;
}
}

View file

@ -30,16 +30,11 @@ package mage.sets.zendikar;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.common.DealsDamageToOpponentTriggeredAbility;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetControlledPermanent;
import mage.filter.common.FilterLandPermanent;
/**
*
@ -57,7 +52,8 @@ public class RuinousMinotaur extends CardImpl {
this.toughness = new MageInt(2);
// Whenever Ruinous Minotaur deals damage to an opponent, sacrifice a land.
this.addAbility(new RuinousMinotaurTriggeredAbility());
this.addAbility(new DealsDamageToOpponentTriggeredAbility(new SacrificeControllerEffect(new FilterLandPermanent(), 1, ""), false, false));
}
public RuinousMinotaur(final RuinousMinotaur card) {
@ -69,38 +65,3 @@ public class RuinousMinotaur extends CardImpl {
return new RuinousMinotaur(this);
}
}
class RuinousMinotaurTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
public RuinousMinotaurTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeTargetEffect(), false);
this.addTarget(new TargetControlledPermanent(filter));
}
public RuinousMinotaurTriggeredAbility(final RuinousMinotaurTriggeredAbility ability) {
super(ability);
}
@Override
public RuinousMinotaurTriggeredAbility copy() {
return new RuinousMinotaurTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId().equals(this.sourceId)
&& game.getOpponents(this.getControllerId()).contains(event.getTargetId());
}
@Override
public String getRule() {
return "Whenever {this} deals damage to an opponent, sacrifice a land.";
}
}

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package org.mage.test.cards.copy;
import mage.constants.PhaseStep;
@ -79,6 +78,7 @@ public class KikiJikiMirrorBreakerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Voice of Resurgence", 1);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
// Flamebreak deals 3 damage to each creature without flying and each player. Creatures dealt damage this way can't be regenerated this turn.
addCard(Zone.HAND, playerB, "Flamebreak");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Put a token that's a copy of target nonlegendary creature you control onto the battlefield. That token has haste. Sacrifice it at the beginning of the next end step.");
@ -97,6 +97,40 @@ public class KikiJikiMirrorBreakerTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Elemental", 2);
}
/**
* Kiki-Jiki, Mirror Breaker creates a copy of Humble Defector, activate
* Humble defector, token gets sacrificed while under opponents control.
*/
@Test
public void testTokenNotSacrificedIfNotControlled() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
// Tap target creature you don't control.
// Overload {3}{U}
addCard(Zone.HAND, playerA, "Blustersquall", 1);
addCard(Zone.BATTLEFIELD, playerB, "Kiki-Jiki, Mirror Breaker", 1);
// {T}: Draw two cards. Target opponent gains control of Humble Defector. Activate this ability only during your turn.
addCard(Zone.BATTLEFIELD, playerB, "Humble Defector", 1);
castSpell(2, PhaseStep.UPKEEP, playerA, "Blustersquall", "Humble Defector"); // Tap nontoken Defector so only the Token can be used later
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{T}: Put a token that's a copy of target nonlegendary creature you control onto the battlefield. That token has haste. Sacrifice it at the beginning of the next end step.");
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: Draw two cards. Target opponent gains control");
setStopAt(3, PhaseStep.UPKEEP);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertHandCount(playerB, 3); // normal 1 draw of turn two + 2 from Defector
assertGraveyardCount(playerA, "Blustersquall", 1);
assertPermanentCount(playerB, "Humble Defector", 1);
assertPermanentCount(playerA, "Humble Defector", 1);
}

View file

@ -36,11 +36,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
public class SpellskiteTest extends CardTestPlayerBase {
/**
* Tests that Wild Defiance triggers for Spellskite if spell target is changed to Spellskite
* Tests that Wild Defiance triggers for Spellskite if spell target is
* changed to Spellskite
*/
@Test
public void testDisabledEffectOnChangeZone() {
@ -68,15 +68,18 @@ public class SpellskiteTest extends CardTestPlayerBase {
}
/**
* If Spellskite changes controller, its activated ability can activate but doesn't resolve properly.
* If Spellskite changes controller, its activated ability can activate but
* doesn't resolve properly.
*
* The specific instance was a Spellskite controlled by Vedalken Shackles. Land was targeted by Frost Titan,
* controller (not owner) of Spellskite paid the redirection cost, ability went on the stack, seemed to resolve,
* The specific instance was a Spellskite controlled by Vedalken Shackles.
* Land was targeted by Frost Titan, controller (not owner) of Spellskite
* paid the redirection cost, ability went on the stack, seemed to resolve,
* target never changed.
*
*/
/**
* TODO: This test fails sometimes when building the complete Test Project -> Find the reason
* TODO: This test fails sometimes when building the complete Test Project
* -> Find the reason
*/
@Test
public void testAfterChangeOfController() {
@ -154,4 +157,44 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertLife(playerB, 20);
}
/**
* My opponent cast Cryptic Command tapping all of my creatures and bouncing
* a Blade Splicer token I had. I activated a Spellskite but got an error
* stating that Spellskite is not a legal target.
*/
@Test
public void testSpellskite2() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
// Choose two -
// Counter target spell;
// or return target permanent to its owner's hand;
// or tap all creatures your opponents control;
// or draw a card.
addCard(Zone.HAND, playerA, "Cryptic Command");
addCard(Zone.BATTLEFIELD, playerB, "Spellskite", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Command", "mode=2Silvercoat Lion");
setModeChoice(playerA, "2"); // return target permanent to its owner's hand
setModeChoice(playerA, "3"); // tap all creatures your opponents control
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Cryptic Command");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Cryptic Command", 1);
assertHandCount(playerB, "Spellskite", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertTapped("Silvercoat Lion", true);
assertLife(playerA, 20);
assertLife(playerB, 20);
}
}

View file

@ -31,7 +31,6 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.DamagePlayerEvent;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
@ -45,7 +44,7 @@ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl
public DealsDamageToOpponentTriggeredAbility(Effect effect) {
this(effect, false, false);
}
}
public DealsDamageToOpponentTriggeredAbility(Effect effect, boolean optional) {
this(effect, optional, false);

View file

@ -1,23 +1,20 @@
package mage.abilities.effects.common;
import java.util.Locale;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.token.Token;
import mage.players.Player;
import mage.util.CardUtil;
/**
* @author Loki
*/
public class CreateTokenTargetEffect extends OneShotEffect {
private Token token;
private DynamicValue amount;
private boolean tapped;
@ -59,14 +56,10 @@ public class CreateTokenTargetEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int value = amount.calculate(game, source, this);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (value < 1) {
return true;
}
if (value > 0) {
return token.putOntoBattlefield(value, game, source.getSourceId(), targetPointer.getFirst(game, source), tapped, attacking);
}
return false;
return true;
}
@Override

View file

@ -1,38 +1,37 @@
/*
* 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.
*/
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
import java.util.UUID;
import mage.constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -42,17 +41,31 @@ import mage.game.permanent.Permanent;
*/
public class SacrificeTargetEffect extends OneShotEffect {
protected UUID playerIdThatHasToSacrifice;
public SacrificeTargetEffect() {
super(Outcome.Sacrifice);
this("");
}
public SacrificeTargetEffect(String text) {
this();
this(text, null);
}
/**
*
* @param text use this text as rule text for the effect
* @param playerIdThatHasToSacrifice only this playerId has to sacrifice
* (others can't)
*/
public SacrificeTargetEffect(String text, UUID playerIdThatHasToSacrifice) {
super(Outcome.Sacrifice);
this.playerIdThatHasToSacrifice = playerIdThatHasToSacrifice;
staticText = text;
}
public SacrificeTargetEffect(final SacrificeTargetEffect effect) {
super(effect);
this.playerIdThatHasToSacrifice = effect.playerIdThatHasToSacrifice;
}
@Override
@ -65,7 +78,7 @@ public class SacrificeTargetEffect extends OneShotEffect {
int affectedTargets = 0;
for (UUID permanentId : targetPointer.getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
if (permanent != null && (playerIdThatHasToSacrifice == null || playerIdThatHasToSacrifice.equals(permanent.getControllerId()))) {
permanent.sacrifice(source.getSourceId(), game);
affectedTargets++;
}

View file

@ -5,9 +5,19 @@ package mage.constants;
* @author North
*/
public enum Zone {
HAND, GRAVEYARD, LIBRARY, BATTLEFIELD, STACK, EXILED, ALL, OUTSIDE, PICK, COMMAND;
public boolean match(Zone zone) {
return (this == zone || this == ALL || zone == ALL);
}
@Override
public String toString() {
if (this.equals(EXILED)) {
return "exile zone";
}
return super.toString(); //To change body of generated methods, choose Tools | Templates.
}
}

View file

@ -2873,19 +2873,12 @@ public abstract class PlayerImpl implements Player, Serializable {
public UUID getCommanderId() {
return this.commanderId;
}
//
// @Override
// public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) {
// return moveCards(cards, fromZone, toZone, source, game, true);
// }
@Override
public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) {
Set<Card> cardList = new HashSet<>();
for (UUID cardId : cards) {
if (fromZone == null) {
fromZone = game.getState().getZone(cardId);
}
fromZone = game.getState().getZone(cardId);
if (fromZone.equals(Zone.BATTLEFIELD)) {
Permanent permanent = game.getPermanent(cardId);
if (permanent != null) {
@ -2901,10 +2894,6 @@ public abstract class PlayerImpl implements Player, Serializable {
return moveCards(cardList, fromZone, toZone, source, game);
}
// @Override
// public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game) {
// return moveCards(card, fromZone, toZone, source, game, true);
// }
@Override
public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game) {
Set<Card> cardList = new HashSet<>();
@ -2914,10 +2903,6 @@ public abstract class PlayerImpl implements Player, Serializable {
return moveCards(cardList, fromZone, toZone, source, game);
}
// @Override
// public boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
// return moveCards(cards, fromZone, toZone, source, game, true);
// }
@Override
public boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
if (cards.isEmpty()) {
@ -2987,22 +2972,19 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, boolean withName) {
boolean result = false;
Zone fromZone = game.getState().getZone(card.getId());
if (fromZone.equals(Zone.BATTLEFIELD) && !(card instanceof Permanent)) {
card = game.getPermanent(card.getId());
}
if (card.moveToZone(Zone.HAND, sourceId, game, false)) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
if (!game.isSimulation()) {
StringBuilder sb = new StringBuilder(this.getLogName()).append(" puts ").append(withName ? card.getLogName() : (card.isFaceDown(game) ? "a face down card" : "a card"));
switch (fromZone) {
case EXILED:
sb.append(" from exile zone ");
break;
default:
sb.append(fromZone != null ? new StringBuilder(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : "");
break;
}
sb.append(card.getOwnerId().equals(this.getId()) ? "into his or her hand" : "into its owner's hand");
game.informPlayers(sb.toString());
game.informPlayers(this.getLogName() + " puts "
+ (withName ? card.getLogName() : (card.isFaceDown(game) ? "a face down card" : "a card"))
+ " from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + " "
+ (card.getOwnerId().equals(this.getId()) ? "into his or her hand" : "into its owner's hand")
);
}
result = true;
}

View file

@ -6,6 +6,7 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.game.Game;
import mage.game.permanent.Permanent;
public class FixedTarget implements TargetPointer {
@ -18,6 +19,12 @@ public class FixedTarget implements TargetPointer {
this.initialized = false;
}
public FixedTarget(Permanent permanent, Game game) {
this.targetId = permanent.getId();
this.zoneChangeCounter = permanent.getZoneChangeCounter(game);
this.initialized = true;
}
/**
* Use this if you already want to fix the target object to the known zone
* now (otherwise the zone will be set if the ability triggers or not at