[ISD] [DKA] refactor some TDFCs

This commit is contained in:
theelk801 2025-07-28 13:50:09 -04:00
parent 2ef506ea7f
commit 69b82f4068
12 changed files with 125 additions and 256 deletions

View file

@ -1,21 +1,18 @@
package mage.cards.a; package mage.cards.a;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetSacrifice;
import java.util.UUID; import java.util.UUID;
@ -24,11 +21,7 @@ import java.util.UUID;
*/ */
public final class ArchdemonOfGreed extends CardImpl { public final class ArchdemonOfGreed extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Human"); private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HUMAN, "Human");
static {
filter.add(SubType.HUMAN.getPredicate());
}
public ArchdemonOfGreed(UUID ownerId, CardSetInfo setInfo) { public ArchdemonOfGreed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
@ -44,7 +37,10 @@ public final class ArchdemonOfGreed extends CardImpl {
this.addAbility(TrampleAbility.getInstance()); this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, sacrifice a Human. If you can't, tap Archdemon of Greed and it deals 9 damage to you. // At the beginning of your upkeep, sacrifice a Human. If you can't, tap Archdemon of Greed and it deals 9 damage to you.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ArchdemonOfGreedEffect())); this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid(
null, new TapSourceEffect(), new SacrificeTargetCost(filter), false
).addOtherwiseEffect(new DamageControllerEffect(9))
.setText("sacrifice a Human. If you can't, tap {this} and it deals 9 damage to you")));
} }
private ArchdemonOfGreed(final ArchdemonOfGreed card) { private ArchdemonOfGreed(final ArchdemonOfGreed card) {
@ -55,48 +51,4 @@ public final class ArchdemonOfGreed extends CardImpl {
public ArchdemonOfGreed copy() { public ArchdemonOfGreed copy() {
return new ArchdemonOfGreed(this); return new ArchdemonOfGreed(this);
} }
static class ArchdemonOfGreedEffect extends OneShotEffect {
public ArchdemonOfGreedEffect() {
super(Outcome.Damage);
this.staticText = "sacrifice a Human. If you can't, tap {this} and it deals 9 damage to you.";
}
private ArchdemonOfGreedEffect(final ArchdemonOfGreedEffect effect) {
super(effect);
}
@Override
public ArchdemonOfGreedEffect copy() {
return new ArchdemonOfGreedEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
// create cost for sacrificing a human
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
TargetSacrifice target = new TargetSacrifice(filter);
// if they can pay the cost, then they must pay
if (target.canChoose(player.getId(), source, game)) {
player.choose(Outcome.Sacrifice, target, source, game);
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
if (humanSacrifice != null) {
// sacrifice the chosen card
return humanSacrifice.sacrifice(source, game);
}
} else {
permanent.tap(source, game);
player.damage(9, source.getSourceId(), source, game);
}
}
return true;
}
return false;
}
}
} }

View file

@ -1,24 +1,24 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.SubType;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import java.util.Optional;
import java.util.UUID;
/** /**
* @author nantuko * @author nantuko
*/ */
@ -35,8 +35,10 @@ public final class CivilizedScholar extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// {tap}: Draw a card, then discard a card. If a creature card is discarded this way, untap Civilized Scholar, then transform it. // {tap}: Draw a card, then discard a card. If a creature card is discarded this way, untap Civilized Scholar, then transform it.
this.addAbility(new SimpleActivatedAbility(new CivilizedScholarEffect(), new TapSourceCost())); Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost());
ability.addEffect(new CivilizedScholarEffect());
this.addAbility(new TransformAbility()); this.addAbility(new TransformAbility());
this.addAbility(ability);
} }
private CivilizedScholar(final CivilizedScholar card) { private CivilizedScholar(final CivilizedScholar card) {
@ -50,12 +52,11 @@ public final class CivilizedScholar extends CardImpl {
} }
class CivilizedScholarEffect extends OneShotEffect { class CivilizedScholarEffect extends OneShotEffect {
CivilizedScholarEffect() { CivilizedScholarEffect() {
super(Outcome.DrawCard); super(Outcome.DrawCard);
staticText = "Draw a card, then discard a card. If a creature card is discarded this way, untap {this}, then transform it"; staticText = ", then discard a card. If a creature card is discarded this way, untap {this}, then transform it";
} }
private CivilizedScholarEffect(final CivilizedScholarEffect effect) { private CivilizedScholarEffect(final CivilizedScholarEffect effect) {
@ -70,18 +71,18 @@ class CivilizedScholarEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player == null) {
player.drawCards(1, source, game);
Card card = player.discardOne(false, false, source, game);
if (card != null && card.isCreature(game)) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.untap(game);
permanent.transform(source, game);
}
}
return true;
}
return false; return false;
} }
Card card = player.discardOne(false, false, source, game);
if (card == null || !card.isCreature(game)) {
return true;
}
Optional.ofNullable(source.getSourcePermanentIfItStillExists(game))
.ifPresent(permanent -> {
permanent.untap(game);
permanent.transform(source, game);
});
return true;
}
} }

View file

@ -1,23 +1,20 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.filter.FilterCard; import mage.constants.SubType;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil;
import java.util.Optional;
import java.util.UUID;
/** /**
* @author Alvin * @author Alvin
@ -51,11 +48,10 @@ public final class DelverOfSecrets extends CardImpl {
class DelverOfSecretsEffect extends OneShotEffect { class DelverOfSecretsEffect extends OneShotEffect {
private static final FilterCard filter = new FilterInstantOrSorceryCard();
public DelverOfSecretsEffect() { public DelverOfSecretsEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "look at the top card of your library. You may reveal that card. If an instant or sorcery card is revealed this way, transform {this}"; this.staticText = "look at the top card of your library. You may reveal that card. " +
"If an instant or sorcery card is revealed this way, transform {this}";
} }
private DelverOfSecretsEffect(final DelverOfSecretsEffect effect) { private DelverOfSecretsEffect(final DelverOfSecretsEffect effect) {
@ -70,25 +66,22 @@ class DelverOfSecretsEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (player == null || !player.getLibrary().hasCards()) {
if (player == null || sourcePermanent == null) {
return false; return false;
} }
if (player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game); Card card = player.getLibrary().getFromTop(game);
if (card == null) { if (card == null) {
return false; return false;
} }
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(card);
cards.add(card); player.lookAtCards(CardUtil.getSourceLogName(game, source), cards, game);
player.lookAtCards(sourcePermanent.getName(), cards, game); if (!player.chooseUse(Outcome.DrawCard, "Reveal the top card of your library?", source, game)) {
if (player.chooseUse(Outcome.DrawCard, "Reveal the top card of your library?", source, game)) { return false;
player.revealCards(sourcePermanent.getName(), cards, game);
if (filter.match(card, game)) {
return new TransformSourceEffect().apply(game, source);
} }
} player.revealCards(source, cards, game);
if (card.isInstantOrSorcery(game)) {
Optional.ofNullable(source.getSourcePermanentIfItStillExists(game))
.ifPresent(permanent -> permanent.transform(source, game));
} }
return true; return true;
} }

View file

@ -1,25 +1,23 @@
package mage.cards.e; package mage.cards.e;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent; import java.util.Optional;
import java.util.UUID;
/** /**
* @author BetaSteward * @author BetaSteward
@ -36,10 +34,16 @@ public final class ElbrusTheBindingBlade extends CardImpl {
// Equipped creature gets +1/+0. // Equipped creature gets +1/+0.
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 0))); this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 0)));
// When equipped creature deals combat damage to a player, unattach Elbrus, the Binding Blade, then transform it. // When equipped creature deals combat damage to a player, unattach Elbrus, the Binding Blade, then transform it.
this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new ElbrusTheBindingBladeEffect(), "equipped", false)); Ability ability = new DealsDamageToAPlayerAttachedTriggeredAbility(
new ElbrusTheBindingBladeEffect(), "equipped", false
);
ability.addEffect(new TransformSourceEffect(true).concatBy(", then"));
this.addAbility(ability);
// Equip {1} // Equip {1}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1), new TargetControlledCreaturePermanent(), false)); this.addAbility(new EquipAbility(1, false));
} }
private ElbrusTheBindingBlade(final ElbrusTheBindingBlade card) { private ElbrusTheBindingBlade(final ElbrusTheBindingBlade card) {
@ -64,20 +68,12 @@ class ElbrusTheBindingBladeEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent equipment = game.getPermanent(source.getSourceId()); Optional.ofNullable(source.getSourcePermanentIfItStillExists(game)).ifPresent(permanent -> permanent.unattach(game));
if (equipment != null && equipment.getAttachedTo() != null) { return true;
Permanent attachedTo = game.getPermanent(equipment.getAttachedTo());
if (attachedTo != null) {
attachedTo.removeAttachment(equipment.getId(), source, game);
equipment.transform(source, game);
}
}
return false;
} }
@Override @Override
public ElbrusTheBindingBladeEffect copy() { public ElbrusTheBindingBladeEffect copy() {
return new ElbrusTheBindingBladeEffect(this); return new ElbrusTheBindingBladeEffect(this);
} }
} }

View file

@ -1,4 +1,3 @@
package mage.cards.g; package mage.cards.g;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -6,6 +5,7 @@ import mage.abilities.LoyaltyAbility;
import mage.abilities.StateTriggeredAbility; import mage.abilities.StateTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -39,13 +39,13 @@ public final class GarrukRelentless extends CardImpl {
this.addAbility(new GarrukRelentlessStateTrigger()); this.addAbility(new GarrukRelentlessStateTrigger());
// 0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him // 0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him
LoyaltyAbility ability1 = new LoyaltyAbility(new GarrukRelentlessDamageEffect(), 0); Ability ability = new LoyaltyAbility(new DamageTargetEffect(3), 0);
ability1.addTarget(new TargetCreaturePermanent()); ability.addEffect(new GarrukRelentlessDamageEffect());
this.addAbility(ability1); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// 0: Create a 2/2 green Wolf creature token. // 0: Create a 2/2 green Wolf creature token.
LoyaltyAbility ability2 = new LoyaltyAbility(new CreateTokenEffect(new WolfToken()), 0); this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfToken()), 0));
this.addAbility(ability2);
} }
private GarrukRelentless(final GarrukRelentless card) { private GarrukRelentless(final GarrukRelentless card) {
@ -89,7 +89,7 @@ class GarrukRelentlessDamageEffect extends OneShotEffect {
GarrukRelentlessDamageEffect() { GarrukRelentlessDamageEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "{this} deals 3 damage to target creature. That creature deals damage equal to its power to him"; staticText = "That creature deals damage equal to its power to him";
} }
private GarrukRelentlessDamageEffect(final GarrukRelentlessDamageEffect effect) { private GarrukRelentlessDamageEffect(final GarrukRelentlessDamageEffect effect) {
@ -98,19 +98,11 @@ class GarrukRelentlessDamageEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent != null) { Permanent creature = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
int damage = permanent.getPower().getValue(); return permanent != null
permanent.damage(3, source.getSourceId(), source, game, false, true); && creature != null
if (damage > 0) { && permanent.damage(creature.getPower().getValue(), creature.getId(), source, game) > 0;
Permanent garruk = game.getPermanent(source.getSourceId());
if (garruk != null) {
garruk.damage(damage, permanent.getId(), source, game, false, true);
}
}
return true;
}
return false;
} }
@Override @Override

View file

@ -1,11 +1,13 @@
package mage.cards.l; package mage.cards.l;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.RemoveAllCountersSourceEffect;
import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
@ -13,12 +15,8 @@ import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID; import java.util.UUID;
@ -27,6 +25,8 @@ import java.util.UUID;
*/ */
public final class LudevicsTestSubject extends CardImpl { public final class LudevicsTestSubject extends CardImpl {
private static final Condition condition = new SourceHasCounterCondition(CounterType.HATCHLING, 5);
public LudevicsTestSubject(UUID ownerId, CardSetInfo setInfo) { public LudevicsTestSubject(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.LIZARD, SubType.EGG); this.subtype.add(SubType.LIZARD, SubType.EGG);
@ -37,10 +37,16 @@ public final class LudevicsTestSubject extends CardImpl {
this.secondSideCardClazz = mage.cards.l.LudevicsAbomination.class; this.secondSideCardClazz = mage.cards.l.LudevicsAbomination.class;
this.addAbility(DefenderAbility.getInstance()); this.addAbility(DefenderAbility.getInstance());
// {1}{U}: Put a hatchling counter on Ludevic's Test Subject. Then if there are five or more hatchling counters on it, remove all of them and transform it. // {1}{U}: Put a hatchling counter on Ludevic's Test Subject. Then if there are five or more hatchling counters on it, remove all of them and transform it.
this.addAbility(new TransformAbility()); this.addAbility(new TransformAbility());
Ability ability = new SimpleActivatedAbility(new AddCountersSourceEffect(CounterType.HATCHLING.createInstance()), new ManaCostsImpl<>("{1}{U}")); Ability ability = new SimpleActivatedAbility(
ability.addEffect(new LudevicsTestSubjectEffect()); new AddCountersSourceEffect(CounterType.HATCHLING.createInstance()), new ManaCostsImpl<>("{1}{U}")
);
ability.addEffect(new ConditionalOneShotEffect(
new RemoveAllCountersSourceEffect(CounterType.HATCHLING), condition,
"Then if there are five or more hatchling counters on it, remove all of them and transform it"
).addEffect(new TransformSourceEffect()));
this.addAbility(ability); this.addAbility(ability);
} }
@ -53,35 +59,3 @@ public final class LudevicsTestSubject extends CardImpl {
return new LudevicsTestSubject(this); return new LudevicsTestSubject(this);
} }
} }
class LudevicsTestSubjectEffect extends OneShotEffect {
LudevicsTestSubjectEffect() {
super(Outcome.Benefit);
staticText = "Then if there are five or more hatchling counters on it, remove all of them and transform it";
}
private LudevicsTestSubjectEffect(final LudevicsTestSubjectEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false;
}
if (permanent.getCounters(game).getCount(CounterType.HATCHLING) >= 5) {
permanent.removeAllCounters(CounterType.HATCHLING.getName(), source, game);
TransformSourceEffect effect = new TransformSourceEffect();
return effect.apply(game, source);
}
return false;
}
@Override
public LudevicsTestSubjectEffect copy() {
return new LudevicsTestSubjectEffect(this);
}
}

View file

@ -19,6 +19,7 @@ import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetOpponentOrPlaneswalker; import mage.target.common.TargetOpponentOrPlaneswalker;
import mage.target.targetpointer.EachTargetPointer;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -69,6 +70,7 @@ class RavagerOfTheFellsEffect extends OneShotEffect {
RavagerOfTheFellsEffect() { RavagerOfTheFellsEffect() {
super(Outcome.Damage); super(Outcome.Damage);
this.setTargetPointer(new EachTargetPointer());
staticText = "it deals 2 damage to target opponent or planeswalker and 2 damage " + staticText = "it deals 2 damage to target opponent or planeswalker and 2 damage " +
"to up to one target creature that player or that planeswalker's controller controls."; "to up to one target creature that player or that planeswalker's controller controls.";
} }
@ -84,10 +86,11 @@ class RavagerOfTheFellsEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
game.damagePlayerOrPermanent(source.getTargets().get(0).getFirstTarget(), 2, source.getSourceId(), source, game, false, true); for (UUID targetId : getTargetPointer().getTargets(game, source)) {
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget()); game.damagePlayerOrPermanent(
if (creature != null) { targetId, 2, source.getSourceId(), source,
creature.damage(2, source.getSourceId(), source, game, false, true); game, false, true
);
} }
return true; return true;
} }

View file

@ -1,8 +1,5 @@
package mage.cards.r; package mage.cards.r;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
@ -12,19 +9,16 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/** /**
* @author intimidatingant * @author intimidatingant
*/ */
public final class RavenousDemon extends CardImpl { public final class RavenousDemon extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Human");
static { private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HUMAN, "Human");
filter.add(SubType.HUMAN.getPredicate());
}
public RavenousDemon(UUID ownerId, CardSetInfo setInfo) { public RavenousDemon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
@ -37,7 +31,7 @@ public final class RavenousDemon extends CardImpl {
// Sacrifice a Human: Transform Ravenous Demon. Activate this ability only any time you could cast a sorcery. // Sacrifice a Human: Transform Ravenous Demon. Activate this ability only any time you could cast a sorcery.
this.addAbility(new TransformAbility()); this.addAbility(new TransformAbility());
this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new SacrificeTargetCost(filter))); this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new SacrificeTargetCost(filter)));
} }
private RavenousDemon(final RavenousDemon card) { private RavenousDemon(final RavenousDemon card) {

View file

@ -68,12 +68,12 @@ class SoulSeizerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || !permanent.transform(source, game)) { if (permanent == null || !permanent.transform(source, game)) {
return false; return false;
} }
Permanent attachTo = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent attachTo = game.getPermanent(getTargetPointer().getFirst(game, source));
return attachTo != null && attachTo.addAttachment(source.getSourceId(), source, game); return attachTo != null && attachTo.addAttachment(permanent.getId(), source, game);
} }
@Override @Override

View file

@ -1,17 +1,16 @@
package mage.cards.t; package mage.cards.t;
import mage.MageInt; import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.filter.StaticFilters;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID; import java.util.UUID;
@ -32,7 +31,10 @@ public final class TovolarsMagehunter extends CardImpl {
this.nightCard = true; this.nightCard = true;
// Whenever an opponent casts a spell, Tovolar's Magehunter deals 2 damage to that player. // Whenever an opponent casts a spell, Tovolar's Magehunter deals 2 damage to that player.
this.addAbility(new TovolarsMagehunterTriggeredAbility()); this.addAbility(new SpellCastOpponentTriggeredAbility(
Zone.BATTLEFIELD, new DamageTargetEffect(2, true, "that player"),
StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.PLAYER
));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Tovolar's Magehunter. // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Tovolar's Magehunter.
this.addAbility(new WerewolfBackTriggeredAbility()); this.addAbility(new WerewolfBackTriggeredAbility());
@ -47,38 +49,3 @@ public final class TovolarsMagehunter extends CardImpl {
return new TovolarsMagehunter(this); return new TovolarsMagehunter(this);
} }
} }
class TovolarsMagehunterTriggeredAbility extends TriggeredAbilityImpl {
TovolarsMagehunterTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(2), false);
}
private TovolarsMagehunterTriggeredAbility(final TovolarsMagehunterTriggeredAbility ability) {
super(ability);
}
@Override
public TovolarsMagehunterTriggeredAbility copy() {
return new TovolarsMagehunterTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getOpponents(controllerId).contains(event.getPlayerId())) {
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever an opponent casts a spell, {this} deals 2 damage to that player.";
}
}

View file

@ -11,11 +11,12 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Controllable;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetArtifactPermanent;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@ -72,16 +73,18 @@ class WerewolfRansackerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) { if (permanent == null) {
return false; return false;
} }
Player player = game.getPlayer(permanent.getControllerId()); permanent.destroy(source, game);
permanent.destroy(source, game, false); if (game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) {
if (game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD || player == null) {
return true; return true;
} }
player.damage(3, source.getSourceId(), source, game); Optional.ofNullable(permanent)
.map(Controllable::getControllerId)
.map(game::getPlayer)
.ifPresent(player -> player.damage(3, source, game));
return true; return true;
} }
} }

View file

@ -1,4 +1,3 @@
package mage.cards.w; package mage.cards.w;
import mage.MageInt; import mage.MageInt;
@ -20,7 +19,6 @@ import mage.game.events.GameEvent;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author BetaSteward * @author BetaSteward
*/ */
public final class WithengarUnbound extends CardImpl { public final class WithengarUnbound extends CardImpl {
@ -40,9 +38,9 @@ public final class WithengarUnbound extends CardImpl {
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
this.addAbility(IntimidateAbility.getInstance()); this.addAbility(IntimidateAbility.getInstance());
this.addAbility(TrampleAbility.getInstance()); this.addAbility(TrampleAbility.getInstance());
// Whenever a player loses the game, put thirteen +1/+1 counters on Withengar Unbound. // Whenever a player loses the game, put thirteen +1/+1 counters on Withengar Unbound.
this.addAbility(new WithengarUnboundTriggeredAbility()); this.addAbility(new WithengarUnboundTriggeredAbility());
} }
private WithengarUnbound(final WithengarUnbound card) { private WithengarUnbound(final WithengarUnbound card) {
@ -57,8 +55,9 @@ public final class WithengarUnbound extends CardImpl {
class WithengarUnboundTriggeredAbility extends TriggeredAbilityImpl { class WithengarUnboundTriggeredAbility extends TriggeredAbilityImpl {
public WithengarUnboundTriggeredAbility() { WithengarUnboundTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(13)), false); super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(13)), false);
setTriggerPhrase("Whenever a player loses the game, ");
} }
private WithengarUnboundTriggeredAbility(final WithengarUnboundTriggeredAbility ability) { private WithengarUnboundTriggeredAbility(final WithengarUnboundTriggeredAbility ability) {
@ -79,9 +78,4 @@ class WithengarUnboundTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
return true; return true;
} }
@Override
public String getRule() {
return "Whenever a player loses the game, put thirteen +1/+1 counters on {this}.";
}
} }