forked from External/mage
Attacks player with creatures triggered ability, Implement [BLC] Echoing Assault (#13764)
Create AttacksPlayerWithCreaturesTriggeredAbility, and tests for that ability via Soaring Lightbringer. Implement Echoing Assault.
This commit is contained in:
parent
a7258604c6
commit
1fe0d92c86
15 changed files with 404 additions and 371 deletions
|
|
@ -1,7 +1,7 @@
|
|||
package mage.cards.d;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
|
|
@ -12,12 +12,11 @@ import mage.cards.CardSetInfo;
|
|||
import mage.cards.Cards;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Controllable;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.DemonToken;
|
||||
import mage.players.Player;
|
||||
|
|
@ -30,6 +29,7 @@ import java.util.UUID;
|
|||
* @author TheElk801
|
||||
*/
|
||||
public final class DemonicCovenant extends CardImpl {
|
||||
FilterPermanent filter = new FilterControlledPermanent(SubType.DEMON,"Demons you control");
|
||||
|
||||
public DemonicCovenant(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.ENCHANTMENT}, "{4}{B}{B}");
|
||||
|
|
@ -37,12 +37,14 @@ public final class DemonicCovenant extends CardImpl {
|
|||
this.subtype.add(SubType.DEMON);
|
||||
|
||||
// Whenever one or more Demons you control attack a player, you draw a card and lose 1 life.
|
||||
this.addAbility(new DemonicCovenantTriggeredAbility());
|
||||
Ability abilityAttack = new AttacksPlayerWithCreaturesTriggeredAbility(new DrawCardSourceControllerEffect(1, true), filter, SetTargetPointer.NONE);
|
||||
abilityAttack.addEffect(new LoseLifeSourceControllerEffect(1).setText("and lose 1 life"));
|
||||
this.addAbility(abilityAttack);
|
||||
|
||||
// At the beginning of your end step, create a 5/5 black Demon creature token with flying, then mill two cards. If two cards that share all their card types were milled this way, sacrifice Demonic Covenant.
|
||||
Ability ability = new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new DemonToken()));
|
||||
ability.addEffect(new DemonicCovenantEffect());
|
||||
this.addAbility(ability);
|
||||
Ability abilityEndStep = new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new DemonToken()));
|
||||
abilityEndStep.addEffect(new DemonicCovenantEffect());
|
||||
this.addAbility(abilityEndStep);
|
||||
}
|
||||
|
||||
private DemonicCovenant(final DemonicCovenant card) {
|
||||
|
|
@ -55,40 +57,6 @@ public final class DemonicCovenant extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class DemonicCovenantTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
DemonicCovenantTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1, true));
|
||||
this.addEffect(new LoseLifeSourceControllerEffect(1).setText("and lose 1 life"));
|
||||
this.setTriggerPhrase("Whenever one or more Demons you control attack a player, ");
|
||||
}
|
||||
|
||||
private DemonicCovenantTriggeredAbility(final DemonicCovenantTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DemonicCovenantTriggeredAbility copy() {
|
||||
return new DemonicCovenantTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return game.getPlayer(event.getTargetId()) != null
|
||||
&& ((DefenderAttackedEvent) event)
|
||||
.getAttackers(game)
|
||||
.stream()
|
||||
.filter(permanent -> permanent.hasSubtype(SubType.DEMON, game))
|
||||
.map(Controllable::getControllerId)
|
||||
.anyMatch(this::isControlledBy);
|
||||
}
|
||||
}
|
||||
|
||||
class DemonicCovenantEffect extends OneShotEffect {
|
||||
|
||||
DemonicCovenantEffect() {
|
||||
|
|
|
|||
107
Mage.Sets/src/mage/cards/e/EchoingAssault.java
Normal file
107
Mage.Sets/src/mage/cards/e/EchoingAssault.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.MenaceAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.filter.predicate.permanent.TokenPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public final class EchoingAssault extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreaturePermanent("nontoken creature that's attacking that player");
|
||||
|
||||
static {
|
||||
filter.add(TokenPredicate.FALSE);
|
||||
filter.add(EchoingAssaultPredicate.instance);
|
||||
}
|
||||
|
||||
public EchoingAssault(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{R}");
|
||||
|
||||
|
||||
// Creature tokens you control have menace.
|
||||
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
|
||||
new MenaceAbility(false), Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURE_TOKENS
|
||||
)));
|
||||
|
||||
// Whenever you attack a player, choose target nontoken creature that's attacking that player. Create a token that's a copy of that creature, except it's 1/1. The token enters tapped and attacking that player. Sacrifice it at the beginning of the next end step.
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(new EchoingAssaultEffect(), SetTargetPointer.NONE);
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private EchoingAssault(final EchoingAssault card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EchoingAssault copy() {
|
||||
return new EchoingAssault(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum EchoingAssaultPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return CardUtil.getEffectValueFromAbility(input.getSource(), "playerAttacked", UUID.class)
|
||||
.filter(uuid -> uuid.equals(game.getCombat().getDefenderId(input.getObject().getId())))
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
class EchoingAssaultEffect extends OneShotEffect {
|
||||
|
||||
EchoingAssaultEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "choose target nontoken creature that's attacking that player. Create a token that's a copy of that creature, except it's 1/1. The token enters tapped and attacking that player. Sacrifice it at the beginning of the next end step.";
|
||||
}
|
||||
|
||||
private EchoingAssaultEffect(final EchoingAssaultEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EchoingAssaultEffect copy() {
|
||||
return new EchoingAssaultEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Object attackedPlayer = getValue("playerAttacked");
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent == null || !(attackedPlayer instanceof UUID)) {
|
||||
return false;
|
||||
}
|
||||
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, false,
|
||||
1, true, true, (UUID) attackedPlayer, 1, 1, false);
|
||||
effect.setSavedPermanent(permanent);
|
||||
effect.apply(game, source);
|
||||
effect.sacrificeTokensCreatedAtNextEndStep(game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package mage.cards.f;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.combat.GoadTargetEffect;
|
||||
|
|
@ -14,7 +14,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
|
@ -29,12 +29,11 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class FirkraagCunningInstigator extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreaturePermanent();
|
||||
private static final FilterPermanent filterDragons = new FilterControlledCreaturePermanent("Dragons you control");
|
||||
private static final FilterPermanent filterHadToAttack = new FilterCreaturePermanent();
|
||||
private static final FilterPermanent filterDragons = new FilterControlledPermanent(SubType.DRAGON, "Dragons you control");
|
||||
|
||||
static {
|
||||
filter.add(FirkraagCunningInstigatorPredicate.instance);
|
||||
filterDragons.add(SubType.DRAGON.getPredicate());
|
||||
filterHadToAttack.add(FirkraagCunningInstigatorPredicate.instance);
|
||||
}
|
||||
|
||||
public FirkraagCunningInstigator(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
|
@ -52,7 +51,7 @@ public final class FirkraagCunningInstigator extends CardImpl {
|
|||
this.addAbility(HasteAbility.getInstance());
|
||||
|
||||
// Whenever one or more Dragons you control attack an opponent, goad target creature that player controls.
|
||||
Ability abilityGoad = new AttacksWithCreaturesTriggeredAbility(Zone.BATTLEFIELD, new GoadTargetEffect(), 1, filterDragons, true);
|
||||
Ability abilityGoad = new AttacksPlayerWithCreaturesTriggeredAbility(new GoadTargetEffect(), 1, filterDragons, SetTargetPointer.PLAYER, true);
|
||||
abilityGoad.addTarget(new TargetPermanent(new FilterCreaturePermanent("target creature that player controls")));
|
||||
abilityGoad.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||
this.addAbility(abilityGoad);
|
||||
|
|
@ -61,7 +60,7 @@ public final class FirkraagCunningInstigator extends CardImpl {
|
|||
Ability ability = new DealsDamageToAPlayerAllTriggeredAbility(
|
||||
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
|
||||
.setText("you put a +1/+1 counter on {this}"),
|
||||
filter, false, SetTargetPointer.NONE,
|
||||
filterHadToAttack, false, SetTargetPointer.NONE,
|
||||
true, false, TargetController.OPPONENT
|
||||
).setTriggerPhrase("Whenever a creature deals combat damage to one of your opponents, " +
|
||||
"if that creature had to attack this combat, ");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package mage.cards.g;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
|
|
@ -17,9 +17,10 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.AttackingPredicate;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -29,16 +30,17 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class GornogTheRedReaper extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.WARRIOR, "Attacking Warriors");
|
||||
private static final FilterPermanent filter2 = new FilterPermanent(SubType.COWARD, "Cowards your opponents control");
|
||||
private static final FilterPermanent filterAttackWarrior = new FilterCreaturePermanent(SubType.WARRIOR, "Attacking Warriors");
|
||||
private static final FilterPermanent filterWarrior = new FilterControlledPermanent(SubType.WARRIOR, "Warriors you control");
|
||||
private static final FilterPermanent filterCoward = new FilterPermanent(SubType.COWARD, "Cowards your opponents control");
|
||||
|
||||
static {
|
||||
filter.add(AttackingPredicate.instance);
|
||||
filter2.add(TargetController.OPPONENT.getControllerPredicate());
|
||||
filterAttackWarrior.add(AttackingPredicate.instance);
|
||||
filterCoward.add(TargetController.OPPONENT.getControllerPredicate());
|
||||
}
|
||||
|
||||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter2, null);
|
||||
private static final Hint hint = new ValueHint(filter2.getMessage(), xValue);
|
||||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filterCoward, null);
|
||||
private static final Hint hint = new ValueHint(filterCoward.getMessage(), xValue);
|
||||
|
||||
public GornogTheRedReaper(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
|
||||
|
|
@ -56,16 +58,16 @@ public final class GornogTheRedReaper extends CardImpl {
|
|||
this.addAbility(new SimpleStaticAbility(new CowardsCantBlockWarriorsEffect()));
|
||||
|
||||
// Whenever one or more Warriors you control attack a player, target creature that player controls becomes a Coward.
|
||||
Ability ability = new AttacksWithCreaturesTriggeredAbility(Zone.BATTLEFIELD,
|
||||
new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.COWARD),
|
||||
1, filter, true);
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(
|
||||
new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.COWARD).setText("target creature that player controls becomes a Coward"),
|
||||
filterWarrior, SetTargetPointer.PLAYER);
|
||||
ability.addTarget(new TargetPermanent());
|
||||
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Attacking Warriors you control get +X/+0, where X is the number of Cowards your opponents control.
|
||||
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
|
||||
xValue, StaticValue.get(0), Duration.WhileOnBattlefield, filter, false
|
||||
xValue, StaticValue.get(0), Duration.WhileOnBattlefield, filterAttackWarrior, false
|
||||
)).addHint(hint));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PutCards;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -27,7 +23,9 @@ public final class HornOfTheMark extends CardImpl {
|
|||
this.supertype.add(SuperType.LEGENDARY);
|
||||
|
||||
// Whenever two or more creatures you control attack a player, look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
this.addAbility(new HornOfTheMarkTriggeredAbility());
|
||||
this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility(
|
||||
new LookLibraryAndPickControllerEffect(5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM),
|
||||
2, StaticFilters.FILTER_CONTROLLED_CREATURES, SetTargetPointer.NONE, false));
|
||||
}
|
||||
|
||||
private HornOfTheMark(final HornOfTheMark card) {
|
||||
|
|
@ -39,39 +37,3 @@ public final class HornOfTheMark extends CardImpl {
|
|||
return new HornOfTheMark(this);
|
||||
}
|
||||
}
|
||||
|
||||
class HornOfTheMarkTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
HornOfTheMarkTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new LookLibraryAndPickControllerEffect(
|
||||
5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM
|
||||
));
|
||||
this.setTriggerPhrase("Whenever two or more creatures you control attack a player, ");
|
||||
}
|
||||
|
||||
private HornOfTheMarkTriggeredAbility(final HornOfTheMarkTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HornOfTheMarkTriggeredAbility copy() {
|
||||
return new HornOfTheMarkTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
DefenderAttackedEvent dEvent = ((DefenderAttackedEvent) event);
|
||||
return game.getPlayer(dEvent.getTargetId()) != null
|
||||
&& dEvent
|
||||
.getAttackers(game)
|
||||
.stream()
|
||||
.map(Controllable::getControllerId)
|
||||
.filter(this::isControlledBy)
|
||||
.count() >= 2;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.common.*;
|
||||
import mage.abilities.effects.common.combat.GoadTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
@ -26,6 +24,7 @@ import java.util.UUID;
|
|||
* @author TheElk801
|
||||
*/
|
||||
public final class KarazikarTheEyeTyrant extends CardImpl {
|
||||
FilterPermanent filter = new FilterCreaturePermanent("creature that player controls");
|
||||
|
||||
public KarazikarTheEyeTyrant(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}");
|
||||
|
|
@ -36,7 +35,11 @@ public final class KarazikarTheEyeTyrant extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
// Whenever you attack a player, tap target creature that player controls and goad it.
|
||||
this.addAbility(new KarazikarTheEyeTyrantFirstTriggeredAbility());
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(new TapTargetEffect(), SetTargetPointer.PLAYER);
|
||||
ability.addEffect(new GoadTargetEffect().setText("goad it. " + GoadTargetEffect.goadReminderText).concatBy("and"));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Whenever an opponent attacks another one of your opponents, you and the attacking player each draw a card and lose 1 life.
|
||||
this.addAbility(new KarazikarTheEyeTyrantSecondTriggeredAbility());
|
||||
|
|
@ -52,49 +55,6 @@ public final class KarazikarTheEyeTyrant extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class KarazikarTheEyeTyrantFirstTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
KarazikarTheEyeTyrantFirstTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new TapTargetEffect(), false);
|
||||
this.addEffect(new GoadTargetEffect());
|
||||
}
|
||||
|
||||
private KarazikarTheEyeTyrantFirstTriggeredAbility(final KarazikarTheEyeTyrantFirstTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KarazikarTheEyeTyrantFirstTriggeredAbility copy() {
|
||||
return new KarazikarTheEyeTyrantFirstTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!isControlledBy(event.getPlayerId())) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(event.getTargetId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
FilterPermanent filter = new FilterCreaturePermanent("creature controlled by " + player.getName());
|
||||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
this.getTargets().clear();
|
||||
this.addTarget(new TargetPermanent(filter));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever you attack a player, tap target creature that player controls and goad it.";
|
||||
}
|
||||
}
|
||||
|
||||
class KarazikarTheEyeTyrantSecondTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
KarazikarTheEyeTyrantSecondTriggeredAbility() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
package mage.cards.l;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterAttackingCreature;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -23,6 +22,12 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class LandrovalHorizonWitness extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterAttackingCreature("attacking creature without flying");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
|
||||
}
|
||||
public LandrovalHorizonWitness(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
|
||||
|
||||
|
|
@ -36,7 +41,11 @@ public final class LandrovalHorizonWitness extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever two or more creatures you control attack a player, target attacking creature without flying gains flying until end of turn.
|
||||
this.addAbility(new LandrovalHorizonWitnessTriggeredAbility());
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(
|
||||
new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn),
|
||||
2, StaticFilters.FILTER_CONTROLLED_CREATURES, SetTargetPointer.NONE, false);
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private LandrovalHorizonWitness(final LandrovalHorizonWitness card) {
|
||||
|
|
@ -48,40 +57,3 @@ public final class LandrovalHorizonWitness extends CardImpl {
|
|||
return new LandrovalHorizonWitness(this);
|
||||
}
|
||||
}
|
||||
|
||||
class LandrovalHorizonWitnessTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterAttackingCreature("attacking creature without flying");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
|
||||
}
|
||||
|
||||
LandrovalHorizonWitnessTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn));
|
||||
this.addTarget(new TargetPermanent(filter));
|
||||
setTriggerPhrase("Whenever two or more creatures you control attack a player, ");
|
||||
}
|
||||
|
||||
private LandrovalHorizonWitnessTriggeredAbility(final LandrovalHorizonWitnessTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LandrovalHorizonWitnessTriggeredAbility copy() {
|
||||
return new LandrovalHorizonWitnessTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return isControlledBy(event.getPlayerId())
|
||||
&& game.getPlayer(event.getTargetId()) != null
|
||||
&& ((DefenderAttackedEvent) event).getAttackers(game).size() >= 2;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.permanent.token.FoodToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -20,6 +19,7 @@ import java.util.UUID;
|
|||
* @author TheElk801
|
||||
*/
|
||||
public final class MeriadocBrandybuck extends CardImpl {
|
||||
FilterPermanent filter = new FilterControlledPermanent(SubType.HALFLING,"Halflings you control");
|
||||
|
||||
public MeriadocBrandybuck(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||
|
|
@ -31,7 +31,7 @@ public final class MeriadocBrandybuck extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Whenever one or more Halflings you control attack a player, create a Food token.
|
||||
this.addAbility(new MeriadocBrandybuckTriggeredAbility());
|
||||
this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility(new CreateTokenEffect(new FoodToken()), filter, SetTargetPointer.NONE));
|
||||
}
|
||||
|
||||
private MeriadocBrandybuck(final MeriadocBrandybuck card) {
|
||||
|
|
@ -43,35 +43,3 @@ public final class MeriadocBrandybuck extends CardImpl {
|
|||
return new MeriadocBrandybuck(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MeriadocBrandybuckTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
MeriadocBrandybuckTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new CreateTokenEffect(new FoodToken()));
|
||||
setTriggerPhrase("Whenever one or more Halflings you control attack a player, ");
|
||||
}
|
||||
|
||||
private MeriadocBrandybuckTriggeredAbility(final MeriadocBrandybuckTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeriadocBrandybuckTriggeredAbility copy() {
|
||||
return new MeriadocBrandybuckTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return isControlledBy(event.getPlayerId())
|
||||
&& game.getPlayer(event.getTargetId()) != null
|
||||
&& ((DefenderAttackedEvent) event)
|
||||
.getAttackers(game)
|
||||
.stream()
|
||||
.anyMatch(permanent -> permanent.hasSubtype(SubType.HALFLING, game));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package mage.cards.n;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
|
|
@ -12,11 +12,10 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.permanent.AttackingPredicate;
|
||||
import mage.filter.predicate.permanent.TokenPredicate;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentToken;
|
||||
|
|
@ -33,11 +32,13 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class NeyaliSunsVanguard extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("attacking tokens");
|
||||
private static final FilterPermanent filterAttacking = new FilterPermanent("attacking tokens");
|
||||
private static final FilterPermanent filterControlled = new FilterControlledPermanent("tokens you control");
|
||||
|
||||
static {
|
||||
filter.add(AttackingPredicate.instance);
|
||||
filter.add(TokenPredicate.TRUE);
|
||||
filterAttacking.add(AttackingPredicate.instance);
|
||||
filterAttacking.add(TokenPredicate.TRUE);
|
||||
filterControlled.add(TokenPredicate.TRUE);
|
||||
}
|
||||
|
||||
public NeyaliSunsVanguard(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
|
@ -51,11 +52,13 @@ public final class NeyaliSunsVanguard extends CardImpl {
|
|||
|
||||
// Attacking tokens you control have double strike.
|
||||
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
|
||||
DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter
|
||||
DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filterAttacking
|
||||
)));
|
||||
|
||||
// Whenever one or more tokens you control attack a player, exile the top card of your library. During any turn you attacked with a token, you may play that card.
|
||||
this.addAbility(new NeyaliSunsVanguardTriggeredAbility());
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(new NeyaliSunsVanguardEffect(), filterControlled, SetTargetPointer.NONE);
|
||||
ability.addWatcher(new NeyaliSunsVanguardWatcher());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private NeyaliSunsVanguard(final NeyaliSunsVanguard card) {
|
||||
|
|
@ -68,49 +71,11 @@ public final class NeyaliSunsVanguard extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class NeyaliSunsVanguardTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
NeyaliSunsVanguardTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new NeyaliSunsVanguardEffect());
|
||||
this.addWatcher(new NeyaliSunsVanguardWatcher());
|
||||
}
|
||||
|
||||
private NeyaliSunsVanguardTriggeredAbility(final NeyaliSunsVanguardTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NeyaliSunsVanguardTriggeredAbility copy() {
|
||||
return new NeyaliSunsVanguardTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return game.getPlayer(event.getTargetId()) != null
|
||||
&& ((DefenderAttackedEvent) event)
|
||||
.getAttackers(game)
|
||||
.stream()
|
||||
.filter(PermanentToken.class::isInstance)
|
||||
.map(Controllable::getControllerId)
|
||||
.anyMatch(this::isControlledBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever one or more tokens you control attack a player, exile the top card of your library. " +
|
||||
"During any turn you attacked with a token, you may play that card.";
|
||||
}
|
||||
}
|
||||
|
||||
class NeyaliSunsVanguardEffect extends OneShotEffect {
|
||||
|
||||
NeyaliSunsVanguardEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.setText("exile the top card of your library. During any turn you attacked with a token, you may play that card.");
|
||||
}
|
||||
|
||||
private NeyaliSunsVanguardEffect(final NeyaliSunsVanguardEffect effect) {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
package mage.cards.o;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.abilities.keyword.MentorAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
|
@ -27,6 +27,12 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class OrdruunMentor extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreaturePermanent("creature that's attacking that player");
|
||||
|
||||
static {
|
||||
filter.add(OrdruunMentorPredicate.instance);
|
||||
}
|
||||
|
||||
public OrdruunMentor(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R/W}");
|
||||
|
||||
|
|
@ -39,7 +45,10 @@ public final class OrdruunMentor extends CardImpl {
|
|||
this.addAbility(new MentorAbility());
|
||||
|
||||
// Whenever you attack a player, target creature that's attacking that player gains first strike until end of turn.
|
||||
this.addAbility(new OrdruunMentorTriggeredAbility());
|
||||
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(
|
||||
new GainAbilityTargetEffect(FirstStrikeAbility.getInstance()), SetTargetPointer.NONE);
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private OrdruunMentor(final OrdruunMentor card) {
|
||||
|
|
@ -51,54 +60,13 @@ public final class OrdruunMentor extends CardImpl {
|
|||
return new OrdruunMentor(this);
|
||||
}
|
||||
}
|
||||
|
||||
class OrdruunMentorTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private enum OrdruunMentorPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return CardUtil.getEffectValueFromAbility(
|
||||
input.getSource(), "playerAttacked", UUID.class
|
||||
)
|
||||
.filter(uuid -> uuid.equals(game.getCombat().getDefenderId(input.getObject().getId())))
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreaturePermanent("creature that's attacking that player");
|
||||
|
||||
static {
|
||||
filter.add(OrdruunMentorPredicate.instance);
|
||||
}
|
||||
|
||||
OrdruunMentorTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new GainAbilityTargetEffect(FirstStrikeAbility.getInstance()).setText(""));
|
||||
this.setTriggerPhrase("Whenever you attack a player, ");
|
||||
this.addTarget(new TargetPermanent(filter));
|
||||
}
|
||||
|
||||
private OrdruunMentorTriggeredAbility(final OrdruunMentorTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
enum OrdruunMentorPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public OrdruunMentorTriggeredAbility copy() {
|
||||
return new OrdruunMentorTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!isControlledBy(event.getPlayerId()) || game.getPlayer(event.getTargetId()) == null) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setValue("playerAttacked", event.getTargetId());
|
||||
return true;
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return CardUtil.getEffectValueFromAbility(input.getSource(), "playerAttacked", UUID.class)
|
||||
.filter(uuid -> uuid.equals(game.getCombat().getDefenderId(input.getObject().getId())))
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package mage.cards.s;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
|
|
@ -13,9 +13,7 @@ import mage.constants.*;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.token.GlimmerToken;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -47,7 +45,7 @@ public final class SoaringLightbringer extends CardImpl {
|
|||
)));
|
||||
|
||||
// Whenever you attack a player, create a 1/1 white Glimmer enchantment creature token that's tapped and attacking that player.
|
||||
this.addAbility(new SoaringLightbringerTriggeredAbility());
|
||||
this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility(new SoaringLightbringerEffect(), SetTargetPointer.PLAYER));
|
||||
}
|
||||
|
||||
private SoaringLightbringer(final SoaringLightbringer card) {
|
||||
|
|
@ -60,37 +58,6 @@ public final class SoaringLightbringer extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class SoaringLightbringerTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
SoaringLightbringerTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new SoaringLightbringerEffect());
|
||||
setTriggerPhrase("Whenever you attack a player, ");
|
||||
}
|
||||
|
||||
private SoaringLightbringerTriggeredAbility(final SoaringLightbringerTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoaringLightbringerTriggeredAbility copy() {
|
||||
return new SoaringLightbringerTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!isControlledBy(event.getPlayerId()) || game.getPlayer(event.getTargetId()) == null) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SoaringLightbringerEffect extends OneShotEffect {
|
||||
|
||||
SoaringLightbringerEffect() {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public final class BloomburrowCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Devilish Valet", 195, Rarity.RARE, mage.cards.d.DevilishValet.class));
|
||||
cards.add(new SetCardInfo("Domri, Anarch of Bolas", 98, Rarity.RARE, mage.cards.d.DomriAnarchOfBolas.class));
|
||||
cards.add(new SetCardInfo("Dusk // Dawn", 138, Rarity.RARE, mage.cards.d.DuskDawn.class));
|
||||
cards.add(new SetCardInfo("Echoing Assault", 24, Rarity.RARE, mage.cards.e.EchoingAssault.class));
|
||||
cards.add(new SetCardInfo("Elspeth, Sun's Champion", 97, Rarity.MYTHIC, mage.cards.e.ElspethSunsChampion.class));
|
||||
cards.add(new SetCardInfo("End-Raze Forerunners", 214, Rarity.RARE, mage.cards.e.EndRazeForerunners.class));
|
||||
cards.add(new SetCardInfo("Esika's Chariot", 215, Rarity.RARE, mage.cards.e.EsikasChariot.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
package org.mage.test.cards.single.dsc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public class SoaringLightbringerTest extends CardTestCommander4Players {
|
||||
|
||||
@Test
|
||||
public void test_AttacksDoubled() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Soaring Lightbringer");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Memnite");
|
||||
|
||||
attack(1, playerA, "Soaring Lightbringer", playerB);
|
||||
attack(1, playerA, "Memnite", playerB);
|
||||
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTappedCount("Glimmer Token", true, 1);
|
||||
assertLife(playerB, 20 - 4 - 1 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AttacksTwo() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Soaring Lightbringer");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Memnite");
|
||||
|
||||
attack(1, playerA, "Soaring Lightbringer", playerB);
|
||||
attack(1, playerA, "Memnite", playerD);
|
||||
|
||||
setChoice(playerA, "Whenever"); // Order triggers
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTappedCount("Glimmer Token", true, 2);
|
||||
assertLife(playerB, 20 - 4 - 1);
|
||||
assertLife(playerD, 20 - 1 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AttacksPlaneswalker() {
|
||||
addCard(Zone.BATTLEFIELD, playerD, "Soaring Lightbringer");
|
||||
addCard(Zone.BATTLEFIELD, playerD, "Memnite");
|
||||
addCard(Zone.HAND, playerA, "Nissa Revane");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nissa Revane");
|
||||
attack(2, playerD, "Memnite", "Nissa Revane");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerD, "Glimmer Token", 0);
|
||||
assertCounterCount("Nissa Revane", CounterType.LOYALTY, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AttacksEnters() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Soaring Lightbringer");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Falconer Adept");
|
||||
|
||||
attack(1, playerA, "Falconer Adept", playerB);
|
||||
setChoice(playerA, "Whenever"); // Order triggers
|
||||
addTarget(playerA, playerC);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTappedCount("Glimmer Token", true, 1);
|
||||
assertTappedCount("Bird Token", true, 1);
|
||||
assertLife(playerB, 20 - 2 - 1);
|
||||
assertLife(playerC, 20 - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DefenderAttackedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.target.targetpointer.FixedTargets;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* based heavily on AttacksWithCreaturesTriggeredAbility
|
||||
* @author notgreat
|
||||
*/
|
||||
public class AttacksPlayerWithCreaturesTriggeredAbility extends TriggeredAbilityImpl {
|
||||
private final FilterPermanent filter;
|
||||
private final int minAttackers;
|
||||
private final boolean onlyOpponents;
|
||||
private final SetTargetPointer setTargetPointer;
|
||||
|
||||
public AttacksPlayerWithCreaturesTriggeredAbility(Effect effect, SetTargetPointer setTargetPointer) {
|
||||
this(effect, StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED, setTargetPointer);
|
||||
}
|
||||
|
||||
public AttacksPlayerWithCreaturesTriggeredAbility(Effect effect, FilterPermanent filter, SetTargetPointer setTargetPointer) {
|
||||
this(effect, 1, filter, setTargetPointer, false);
|
||||
}
|
||||
|
||||
public AttacksPlayerWithCreaturesTriggeredAbility(Effect effect, int minAttackers, FilterPermanent filter, SetTargetPointer setTargetPointer, boolean onlyOpponents) {
|
||||
this(Zone.BATTLEFIELD, effect, minAttackers, filter, setTargetPointer, onlyOpponents, false);
|
||||
}
|
||||
|
||||
public AttacksPlayerWithCreaturesTriggeredAbility(Zone zone, Effect effect, int minAttackers, FilterPermanent filter, SetTargetPointer setTargetPointer, boolean onlyOpponents, boolean optional) {
|
||||
super(zone, effect, optional);
|
||||
this.filter = filter;
|
||||
this.minAttackers = minAttackers;
|
||||
this.onlyOpponents = onlyOpponents;
|
||||
this.setTargetPointer = setTargetPointer;
|
||||
if (minAttackers == 1 && StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED.equals(filter) && !onlyOpponents) {
|
||||
setTriggerPhrase("Whenever you attack a player, ");
|
||||
} else {
|
||||
setTriggerPhrase("Whenever " + CardUtil.numberToText(minAttackers) + " or more " + filter.getMessage() +
|
||||
" attack " + (onlyOpponents ? "an opponent" : "a player") + ", ");
|
||||
}
|
||||
}
|
||||
|
||||
protected AttacksPlayerWithCreaturesTriggeredAbility(final AttacksPlayerWithCreaturesTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.filter = ability.filter;
|
||||
this.minAttackers = ability.minAttackers;
|
||||
this.onlyOpponents = ability.onlyOpponents;
|
||||
this.setTargetPointer = ability.setTargetPointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttacksPlayerWithCreaturesTriggeredAbility copy() {
|
||||
return new AttacksPlayerWithCreaturesTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Player player = game.getPlayer(getControllerId());
|
||||
UUID attackedId = event.getTargetId();
|
||||
if (player == null || game.getPlayer(attackedId) == null) {
|
||||
return false;
|
||||
}
|
||||
DefenderAttackedEvent attackedEvent = (DefenderAttackedEvent) event;
|
||||
List<Permanent> attackers = attackedEvent.getAttackers(game).stream()
|
||||
.filter(permanent -> filter.match(permanent, controllerId, this, game))
|
||||
.collect(Collectors.toList());
|
||||
if (attackers.size() < minAttackers || (onlyOpponents && !game.isOpponent(player, attackedId))) {
|
||||
return false;
|
||||
}
|
||||
switch (setTargetPointer){
|
||||
case NONE:
|
||||
break;
|
||||
case PLAYER:
|
||||
getEffects().setTargetPointer(new FixedTarget(attackedId));
|
||||
break;
|
||||
case PERMANENT:
|
||||
getEffects().setTargetPointer(new FixedTargets(new ArrayList<>(attackers), game));
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unexpected setTargetPointer in AttacksPlayerWithCreaturesTriggeredAbility: " + setTargetPointer);
|
||||
|
||||
}
|
||||
this.getEffects().setValue("playerAttacked",attackedId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ public class GoadTargetEffect extends ContinuousEffectImpl {
|
|||
* turn of the controller of that spell or ability, that creature attacks
|
||||
* each combat if able and attacks a player other than that player if able.
|
||||
*/
|
||||
public static String goadReminderText = "<i>(Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)</i>";
|
||||
public GoadTargetEffect() {
|
||||
this(Duration.UntilYourNextTurn);
|
||||
}
|
||||
|
|
@ -74,6 +75,6 @@ public class GoadTargetEffect extends ContinuousEffectImpl {
|
|||
return staticText;
|
||||
}
|
||||
return "goad " + getTargetPointer().describeTargets(mode.getTargets(), "that creature")
|
||||
+ ". <i>(Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)</i>";
|
||||
+ ". "+goadReminderText;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue