Rework implementation of anchor words (#13518)

* refactor anchor word implementation

* fix error

* [TDM] Implement Windcrag Siege
This commit is contained in:
Evan Kranzler 2025-04-09 13:24:57 -04:00 committed by GitHub
parent 3c6e055f41
commit 56a05a7843
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 610 additions and 638 deletions

View file

@ -1,11 +1,8 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect; import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
@ -14,31 +11,44 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.ModeChoice;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author Eirkei * @author Eirkei
*/ */
public final class AshlingsPrerogative extends CardImpl { public final class AshlingsPrerogative extends CardImpl {
private static final FilterPermanent filterMatch
= new FilterCreaturePermanent("each creature with mana value of the chosen quality");
private static final FilterPermanent filterNotMatch
= new FilterCreaturePermanent("each creature without mana value of the chosen quality");
static {
filterMatch.add(AshlingsPrerogativePredicate.WITH);
filterNotMatch.add(AshlingsPrerogativePredicate.WITHOUT);
}
public AshlingsPrerogative(UUID ownerId, CardSetInfo setInfo) { public AshlingsPrerogative(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
// As Ashling's Prerogative enters the battlefield, choose odd or even. // As Ashling's Prerogative enters the battlefield, choose odd or even.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Odd or even?", "Odd", "Even"), null, "As {this} enters, choose odd or even. <i>(Zero is even.)</i>", "")); this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ODD, ModeChoice.EVEN)));
// Each creature with converted mana cost of the chosen value has haste. // Each creature with converted mana cost of the chosen value has haste.
this.addAbility(new SimpleStaticAbility(new AshlingsPrerogativeCorrectOddityEffect())); this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect(
HasteAbility.getInstance(), Duration.WhileOnBattlefield, filterMatch
)));
// Each creature without converted mana cost of the chosen value enters the battlefield tapped. // Each creature without converted mana cost of the chosen value enters the battlefield tapped.
this.addAbility(new SimpleStaticAbility(new AshlingsPrerogativeIncorrectOddityEffect())); this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(filterNotMatch)));
} }
private AshlingsPrerogative(final AshlingsPrerogative card) { private AshlingsPrerogative(final AshlingsPrerogative card) {
@ -51,67 +61,23 @@ public final class AshlingsPrerogative extends CardImpl {
} }
} }
class AshlingsPrerogativeIncorrectOddityEffect extends PermanentsEnterBattlefieldTappedEffect { enum AshlingsPrerogativePredicate implements ObjectSourcePlayerPredicate<Permanent> {
WITH(true),
WITHOUT(false);
private final boolean match;
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Each creature without mana value of the chosen quality"); AshlingsPrerogativePredicate(boolean match) {
private static final ModeChoiceSourceCondition oddCondition = new ModeChoiceSourceCondition("Odd"); this.match = match;
public AshlingsPrerogativeIncorrectOddityEffect() {
super(creaturefilter);
staticText = "Each creature without mana value of the chosen quality enters the battlefield tapped.";
}
private AshlingsPrerogativeIncorrectOddityEffect(final AshlingsPrerogativeIncorrectOddityEffect effect) {
super(effect);
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
int incorrectModResult; if (ModeChoice.ODD.checkMode(game, input.getSource())) {
return (input.getObject().getManaValue() % 2 == 1) == match;
if (oddCondition.apply(game, source)) { } else if (ModeChoice.EVEN.checkMode(game, input.getSource())) {
incorrectModResult = 0; return (input.getObject().getManaValue() % 2 == 0) == match;
} else { } else {
incorrectModResult = 1; return false;
} }
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
return permanent != null && creaturefilter.match(permanent, game) && permanent.getManaValue() % 2 == incorrectModResult;
}
@Override
public AshlingsPrerogativeIncorrectOddityEffect copy() {
return new AshlingsPrerogativeIncorrectOddityEffect(this);
}
}
class AshlingsPrerogativeCorrectOddityEffect extends GainAbilityAllEffect {
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Each creature with mana value of the chosen quality");
private static final ModeChoiceSourceCondition oddCondition = new ModeChoiceSourceCondition("Odd");
public AshlingsPrerogativeCorrectOddityEffect() {
super(HasteAbility.getInstance(), Duration.WhileOnBattlefield, creaturefilter);
staticText = "Each creature with mana value of the chosen quality has haste.";
}
private AshlingsPrerogativeCorrectOddityEffect(final AshlingsPrerogativeCorrectOddityEffect effect) {
super(effect);
}
@Override
protected boolean selectedByRuntimeData(Permanent permanent, Ability source, Game game) {
int correctModResult;
if (oddCondition.apply(game, source)) {
correctModResult = 1;
} else {
correctModResult = 0;
}
return permanent != null && creaturefilter.match(permanent, game) && permanent.getManaValue() % 2 == correctModResult;
}
@Override
public AshlingsPrerogativeCorrectOddityEffect copy() {
return new AshlingsPrerogativeCorrectOddityEffect(this);
} }
} }

View file

@ -1,17 +1,17 @@
package mage.cards.b; package mage.cards.b;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.condition.Condition; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.CreatureDiedControlledCondition; import mage.abilities.condition.common.CreatureDiedControlledCondition;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.SacrificeOpponentsEffect; import mage.abilities.effects.common.SacrificeOpponentsEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
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.ModeChoice;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
@ -22,35 +22,25 @@ import java.util.UUID;
*/ */
public final class BarrensteppeSiege extends CardImpl { public final class BarrensteppeSiege extends CardImpl {
private static final Condition condition1 = new ModeChoiceSourceCondition("Abzan");
private static final String rule1 = "&bull Abzan &mdash; At the beginning of your end step, " +
"put a +1/+1 counter on each creature you control.";
private static final Condition condition2 = new ModeChoiceSourceCondition("Mardu");
private static final String rule2 = "&bull Mardu &mdash; At the beginning of your end step, " +
"if a creature died under your control this turn, each opponent sacrifices a creature of their choice.";
public BarrensteppeSiege(UUID ownerId, CardSetInfo setInfo) { public BarrensteppeSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{B}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{B}");
// As this enchantment enters, choose Abzan or Mardu. // As this enchantment enters, choose Abzan or Mardu.
this.addAbility(new EntersBattlefieldAbility( this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ABZAN, ModeChoice.MARDU)));
new ChooseModeEffect("Abzan or Mardu?", "Abzan", "Mardu"),
null, "As {this} enters, choose Abzan or Mardu.", ""
));
// * Abzan -- At the beginning of your end step, put a +1/+1 counter on each creature you control. // * Abzan -- At the beginning of your end step, put a +1/+1 counter on each creature you control.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfEndStepTriggeredAbility(new AddCountersAllEffect( new BeginningOfEndStepTriggeredAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
)), condition1, rule1 )), ModeChoice.ABZAN
)); )));
// * Mardu -- At the beginning of your end step, if a creature died under your control this turn, each opponent sacrifices a creature of their choice. // * Mardu -- At the beginning of your end step, if a creature died under your control this turn, each opponent sacrifices a creature of their choice.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfEndStepTriggeredAbility( new BeginningOfEndStepTriggeredAbility(
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE) new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE)
).withInterveningIf(CreatureDiedControlledCondition.instance), condition2, rule2 ).withInterveningIf(CreatureDiedControlledCondition.instance), ModeChoice.MARDU
)); )));
} }
private BarrensteppeSiege(final BarrensteppeSiege card) { private BarrensteppeSiege(final BarrensteppeSiege card) {

View file

@ -1,33 +1,35 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
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.ComparisonType; import mage.constants.ComparisonType;
import mage.constants.ModeChoice;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/** /**
* @author Cguy7777 * @author Cguy7777
*/ */
public final class BattleOfHooverDam extends CardImpl { public final class BattleOfHooverDam extends CardImpl {
private static final FilterCreatureCard filter = new FilterCreatureCard(); private static final FilterCard filter = new FilterCreatureCard();
static { static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4)); filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
@ -37,32 +39,23 @@ public final class BattleOfHooverDam extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
// As Battle of Hoover Dam enters the battlefield, choose NCR or Legion. // As Battle of Hoover Dam enters the battlefield, choose NCR or Legion.
this.addAbility(new AsEntersBattlefieldAbility( this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.NCR, ModeChoice.LEGION)));
new ChooseModeEffect("NCR or Legion?", "NCR", "Legion")));
// * NCR -- At the beginning of your end step, return target creature card with mana value 3 or less // * NCR -- At the beginning of your end step, return target creature card with mana value 3 or less
// from your graveyard to the battlefield with a finality counter on it. // from your graveyard to the battlefield with a finality counter on it.
Ability ncrAbility = new ConditionalTriggeredAbility( Ability ability = new BeginningOfEndStepTriggeredAbility(
new BeginningOfEndStepTriggeredAbility(
new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.FINALITY.createInstance()) new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.FINALITY.createInstance())
), );
new ModeChoiceSourceCondition("NCR"), ability.addTarget(new TargetCardInYourGraveyard(filter));
"&bull NCR &mdash; At the beginning of your end step, return target creature card with " + this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.NCR)));
"mana value 3 or less from your graveyard to the battlefield with a finality counter on it.");
ncrAbility.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ncrAbility);
// * Legion -- Whenever a creature you control dies, put two +1/+1 counters on target creature you control. // * Legion -- Whenever a creature you control dies, put two +1/+1 counters on target creature you control.
Ability legionAbility = new ConditionalTriggeredAbility( ability = new DiesCreatureTriggeredAbility(
new DiesCreatureTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)),
false, false, StaticFilters.FILTER_CONTROLLED_A_CREATURE
StaticFilters.FILTER_CONTROLLED_A_CREATURE), );
new ModeChoiceSourceCondition("Legion"), ability.addTarget(new TargetControlledCreaturePermanent());
"&bull Legion &mdash; Whenever a creature you control dies, " + this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.LEGION)));
"put two +1/+1 counters on target creature you control.");
legionAbility.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(legionAbility);
} }
private BattleOfHooverDam(final BattleOfHooverDam card) { private BattleOfHooverDam(final BattleOfHooverDam card) {

View file

@ -1,23 +1,20 @@
package mage.cards.c; package mage.cards.c;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
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.ModeChoice;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
@ -28,36 +25,29 @@ import java.util.UUID;
*/ */
public final class CitadelSiege extends CardImpl { public final class CitadelSiege extends CardImpl {
private static final String ruleTrigger1 = "&bull Khans &mdash; At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.";
private static final String ruleTrigger2 = "&bull Dragons &mdash; At the beginning of combat on each opponent's turn, tap target creature that player controls.";
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by the active player"); private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by the active player");
static { static {
filter.add(CitadelSiegePredicate.instance); filter.add(TargetController.ACTIVE.getControllerPredicate());
} }
public CitadelSiege(UUID ownerId, CardSetInfo setInfo) { public CitadelSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
// As Citadel Siege enters the battlefield, choose Khans or Dragons. // As Citadel Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
"As {this} enters, choose Khans or Dragons.", ""));
// * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control. // * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.
Ability ability = new ConditionalTriggeredAbility( Ability ability = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)));
new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2))),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1);
ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.KHANS)));
// * Dragons - At the beginning of combat on each opponent's turn, tap target creature that player controls. // * Dragons - At the beginning of combat on each opponent's turn, tap target creature that player controls.
ability = new ConditionalTriggeredAbility( ability = new BeginningOfCombatTriggeredAbility(
new BeginningOfCombatTriggeredAbility(TargetController.OPPONENT, new TapTargetEffect(), false), TargetController.OPPONENT, new TapTargetEffect("tap target creature that player controls"), false
new ModeChoiceSourceCondition("Dragons"), );
ruleTrigger2);
ability.addTarget(new TargetCreaturePermanent(filter)); ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.DRAGONS)));
} }
private CitadelSiege(final CitadelSiege card) { private CitadelSiege(final CitadelSiege card) {
@ -69,12 +59,3 @@ public final class CitadelSiege extends CardImpl {
return new CitadelSiege(this); return new CitadelSiege(this);
} }
} }
enum CitadelSiegePredicate implements Predicate<Permanent> {
instance;
@Override
public boolean apply(Permanent input, Game game) {
return input.getControllerId().equals(game.getActivePlayerId());
}
}

View file

@ -3,17 +3,18 @@ package mage.cards.f;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.mana.AddManaToManaPoolSourceControllerEffect; import mage.abilities.effects.mana.AddManaToManaPoolSourceControllerEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate; import mage.filter.predicate.mageobject.AbilityPredicate;
@ -29,37 +30,28 @@ import java.util.UUID;
*/ */
public final class FrontierSiege extends CardImpl { public final class FrontierSiege extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature with flying"); private static final FilterPermanent filter = new FilterCreaturePermanent("a creature with flying you control");
static { static {
filter.add(TargetController.YOU.getControllerPredicate()); filter.add(TargetController.YOU.getControllerPredicate());
filter.add(new AbilityPredicate(FlyingAbility.class)); filter.add(new AbilityPredicate(FlyingAbility.class));
} }
private static final String ruleTrigger1 = "&bull Khans &mdash; At the beginning of each of your main phases, add {G}{G}.";
private static final String ruleTrigger2 = "&bull Dragons &mdash; Whenever a creature with flying you control enters, you may have it fight target creature you don't control.";
public FrontierSiege(UUID ownerId, CardSetInfo setInfo) { public FrontierSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
// As Frontier Siege enters the battlefield, choose Khans or Dragons. // As Frontier Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
"As {this} enters, choose Khans or Dragons.", ""));
// * Khans - At the beginning of each of your main phases, add {G}{G}. // * Khans - At the beginning of each of your main phases, add {G}{G}.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(new FrontierSiegeKhansTriggeredAbility(), ModeChoice.KHANS)));
new FrontierSiegeKhansTriggeredAbility(),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1));
// * Dragons - Whenever a creature with flying you control enters, you may have it fight target creature you don't control. // * Dragons - Whenever a creature with flying you control enters, you may have it fight target creature you don't control.
Ability ability2 = new ConditionalTriggeredAbility( Ability ability = new EntersBattlefieldAllTriggeredAbility(
new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new FrontierSiegeFightEffect(), filter, true, SetTargetPointer.PERMANENT), Zone.BATTLEFIELD, new FrontierSiegeFightEffect(), filter, true, SetTargetPointer.PERMANENT
new ModeChoiceSourceCondition("Dragons"), );
ruleTrigger2); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL));
ability2.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.DRAGONS)));
this.addAbility(ability2);
} }
private FrontierSiege(final FrontierSiege card) { private FrontierSiege(final FrontierSiege card) {

View file

@ -1,65 +1,54 @@
package mage.cards.f; package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility; import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
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.Duration; import mage.constants.Duration;
import mage.constants.ModeChoice;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import java.util.UUID;
/** /**
*
* @author androosss * @author androosss
*/ */
public final class FrostcliffSiege extends CardImpl { public final class FrostcliffSiege extends CardImpl {
private static final String rule1Trigger = "&bull; Jeskai &mdash; Whenever one or more creatures you control deal combat damage to a player, draw a card.";
public FrostcliffSiege(UUID ownerId, CardSetInfo setInfo) { public FrostcliffSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{R}");
// As this enchantment enters, choose Jeskai or Temur. // As this enchantment enters, choose Jeskai or Temur.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Jeskai or Temur?", "Jeskai", "Temur"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.JESKAI, ModeChoice.TEMUR)));
"As {this} enters, choose Jeskai or Temur.", ""));
// * Jeskai -- Whenever one or more creatures you control deal combat damage to a player, draw a card. // * Jeskai -- Whenever one or more creatures you control deal combat damage to a player, draw a card.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new OneOrMoreCombatDamagePlayerTriggeredAbility(new DrawCardSourceControllerEffect(1)), new OneOrMoreCombatDamagePlayerTriggeredAbility(new DrawCardSourceControllerEffect(1)), ModeChoice.JESKAI
new ModeChoiceSourceCondition("Jeskai"), )));
rule1Trigger));
// * Temur -- Creatures you control get +1/+0 and have trample and haste. // * Temur -- Creatures you control get +1/+0 and have trample and haste.
Ability temurAbility = new SimpleStaticAbility(new ConditionalContinuousEffect( Ability ability = new SimpleStaticAbility(
new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield), new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield)
new ModeChoiceSourceCondition("Temur"), );
"&bull; Temur &mdash; Creatures you control get +1/+0" ability.addEffect(new GainAbilityControlledEffect(
)); TrampleAbility.getInstance(), Duration.WhileOnBattlefield,
temurAbility.addEffect(new ConditionalContinuousEffect( StaticFilters.FILTER_PERMANENT_CREATURES
new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES), ).setText("and have trample"));
new ModeChoiceSourceCondition("Temur"), ability.addEffect(new GainAbilityControlledEffect(
"and have trample" HasteAbility.getInstance(), Duration.WhileOnBattlefield,
)); StaticFilters.FILTER_PERMANENT_CREATURES
temurAbility.addEffect(new ConditionalContinuousEffect( ).setText("and haste"));
new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES), this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.TEMUR)));
new ModeChoiceSourceCondition("Temur"),
"and haste."
));
this.addAbility(temurAbility);
} }
private FrostcliffSiege(final FrostcliffSiege card) { private FrostcliffSiege(final FrostcliffSiege card) {

View file

@ -1,58 +1,45 @@
package mage.cards.g; package mage.cards.g;
import java.util.UUID; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalAsThoughEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.MillCardsTargetEffect; import mage.abilities.effects.common.MillCardsTargetEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.ruleModifying.PlayFromGraveyardControllerEffect; import mage.abilities.effects.common.ruleModifying.PlayFromGraveyardControllerEffect;
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.filter.FilterSpell; import mage.constants.ModeChoice;
import mage.filter.predicate.Predicates; import mage.filter.StaticFilters;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.UUID;
/** /**
*
* @author androosss * @author androosss
*/ */
public final class GlacierwoodSiege extends CardImpl { public final class GlacierwoodSiege extends CardImpl {
private static final FilterSpell filter = new FilterSpell("an instant or sorcery spell");
static {
filter.add(Predicates.or(
CardType.INSTANT.getPredicate(),
CardType.SORCERY.getPredicate()));
}
public GlacierwoodSiege(UUID ownerId, CardSetInfo setInfo) { public GlacierwoodSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{U}");
// As this enchantment enters, choose Temur or Sultai. // As this enchantment enters, choose Temur or Sultai.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Temur or Sultai?", "Temur", "Sultai"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.TEMUR, ModeChoice.SULTAI)));
"As {this} enters, choose Temur or Sultai.", ""));
// * Temur -- Whenever you cast an instant or sorcery spell, target player mills four cards. // * Temur -- Whenever you cast an instant or sorcery spell, target player mills four cards.
TriggeredAbility temurAbility = new SpellCastControllerTriggeredAbility(new MillCardsTargetEffect(4), filter, false); Ability ability = new SpellCastControllerTriggeredAbility(
temurAbility.addTarget(new TargetPlayer()); new MillCardsTargetEffect(4),
this.addAbility(new ConditionalTriggeredAbility( StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
temurAbility, );
new ModeChoiceSourceCondition("Temur"), ability.addTarget(new TargetPlayer());
"&bull; Temur &mdash; Whenever you cast an instant or sorcery spell, target player mills four cards.")); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.TEMUR)));
// * Sultai -- You may play lands from your graveyard. // * Sultai -- You may play lands from your graveyard.
this.addAbility(new SimpleStaticAbility(new ConditionalAsThoughEffect( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
PlayFromGraveyardControllerEffect.playLands(), PlayFromGraveyardControllerEffect.playLands(), ModeChoice.SULTAI
new ModeChoiceSourceCondition("Sultai")).setText("&bull; Sultai &mdash; You may play lands from your graveyard.") )));
));
} }
private GlacierwoodSiege(final GlacierwoodSiege card) { private GlacierwoodSiege(final GlacierwoodSiege card) {

View file

@ -1,16 +1,13 @@
package mage.cards.i; package mage.cards.i;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.replacement.AdditionalTriggersAttackingReplacementEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.SubType;
import mage.game.events.GameEvent; import mage.constants.SuperType;
import mage.game.events.NumberOfTriggersEvent;
import mage.game.permanent.Permanent;
import java.util.UUID; import java.util.UUID;
@ -29,7 +26,7 @@ public final class IsshinTwoHeavensAsOne extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// If a creature attacking causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time. // If a creature attacking causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
this.addAbility(new SimpleStaticAbility(new IsshinTwoHeavensAsOneEffect())); this.addAbility(new SimpleStaticAbility(new AdditionalTriggersAttackingReplacementEffect(false)));
} }
private IsshinTwoHeavensAsOne(final IsshinTwoHeavensAsOne card) { private IsshinTwoHeavensAsOne(final IsshinTwoHeavensAsOne card) {
@ -41,54 +38,3 @@ public final class IsshinTwoHeavensAsOne extends CardImpl {
return new IsshinTwoHeavensAsOne(this); return new IsshinTwoHeavensAsOne(this);
} }
} }
class IsshinTwoHeavensAsOneEffect extends ReplacementEffectImpl {
IsshinTwoHeavensAsOneEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "if a creature attacking causes a triggered ability " +
"of a permanent you control to trigger, that ability triggers an additional time";
}
private IsshinTwoHeavensAsOneEffect(final IsshinTwoHeavensAsOneEffect effect) {
super(effect);
}
@Override
public IsshinTwoHeavensAsOneEffect copy() {
return new IsshinTwoHeavensAsOneEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event;
Permanent sourcePermanent = game.getPermanent(numberOfTriggersEvent.getSourceId());
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
return false;
}
GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent();
if (sourceEvent == null) {
return false;
}
switch (sourceEvent.getType()) {
case ATTACKER_DECLARED:
case DECLARED_ATTACKERS:
case DEFENDER_ATTACKED:
return true;
}
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(event.getAmount() + 1);
return false;
}
}

View file

@ -10,6 +10,7 @@ import mage.abilities.keyword.ProtectionAbility;
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.ModeChoice;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.FilterObject; import mage.filter.FilterObject;
import mage.filter.predicate.mageobject.ManaValueParityPredicate; import mage.filter.predicate.mageobject.ManaValueParityPredicate;
@ -31,10 +32,7 @@ public final class LavabrinkVenturer extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// As Lavabrink Venturer enters the battlefield, choose odd or even. // As Lavabrink Venturer enters the battlefield, choose odd or even.
this.addAbility(new AsEntersBattlefieldAbility( this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ODD, ModeChoice.EVEN)));
new ChooseModeEffect("Odd or even?", "Odd", "Even"),
"choose odd or even. <i>(Zero is even.)</i>"
));
// Lavabrink Venturer has protection from each converted mana cost of the chosen value. // Lavabrink Venturer has protection from each converted mana cost of the chosen value.
this.addAbility(new SimpleStaticAbility(new LavabrinkVenturerEffect())); this.addAbility(new SimpleStaticAbility(new LavabrinkVenturerEffect()));
@ -75,18 +73,11 @@ class LavabrinkVenturerEffect extends GainAbilitySourceEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
String chosenMode = (String) game.getState().getValue(source.getSourceId() + "_modeChoice"); if (ModeChoice.ODD.checkMode(game, source)) {
if (chosenMode == null) {
return false;
}
switch (chosenMode) {
case "Odd":
this.ability = new ProtectionAbility(oddFilter); this.ability = new ProtectionAbility(oddFilter);
break; } else if (ModeChoice.EVEN.checkMode(game, source)) {
case "Even":
this.ability = new ProtectionAbility(evenFilter); this.ability = new ProtectionAbility(evenFilter);
break; } else {
default:
return false; return false;
} }
return super.apply(game, source); return super.apply(game, source);

View file

@ -1,22 +1,21 @@
package mage.cards.m; package mage.cards.m;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
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.ModeChoice;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactSpell;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.MyrToken; import mage.game.permanent.token.MyrToken;
import mage.players.Player; import mage.players.Player;
@ -29,33 +28,23 @@ import java.util.UUID;
*/ */
public final class MirrodinBesieged extends CardImpl { public final class MirrodinBesieged extends CardImpl {
private static final String ruleTrigger1 = "&bull Mirran &mdash; Whenever you cast an artifact spell, " +
"create a 1/1 colorless Myr artifact creature token.";
private static final String ruleTrigger2 = "&bull Phyrexian &mdash; At the beginning of your end step, " +
"draw a card, then discard a card. Then if there are fifteen or more artifact cards in your graveyard, " +
"target opponent loses the game.";
private static final FilterSpell filter = new FilterArtifactSpell();
public MirrodinBesieged(UUID ownerId, CardSetInfo setInfo) { public MirrodinBesieged(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// As Mirrodin Besieged enters the battlefield, choose Mirran or Phyrexian. // As Mirrodin Besieged enters the battlefield, choose Mirran or Phyrexian.
this.addAbility(new EntersBattlefieldAbility( this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.MIRRAN, ModeChoice.PHYREXIAN)));
new ChooseModeEffect("Mirran or Phyrexian?", "Mirran", "Phyrexian"),
null, "As {this} enters, choose Mirran or Phyrexian.", ""
));
// Mirran Whenever you cast an artifact spell, create a 1/1 colorless Myr artifact creature token. // Mirran Whenever you cast an artifact spell, create a 1/1 colorless Myr artifact creature token.
this.addAbility(new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new CreateTokenEffect(new MyrToken()), filter, false new SpellCastControllerTriggeredAbility(
), new ModeChoiceSourceCondition("Mirran"), ruleTrigger1)); new CreateTokenEffect(new MyrToken()), StaticFilters.FILTER_SPELL_AN_ARTIFACT, false
), ModeChoice.MIRRAN
)));
// Phyrexian At the beginning of your end step, draw a card, then discard a card. Then if there are fifteen or more artifact cards in your graveyard, target opponent loses the game. // Phyrexian At the beginning of your end step, draw a card, then discard a card. Then if there are fifteen or more artifact cards in your graveyard, target opponent loses the game.
Ability ability = new ConditionalTriggeredAbility(new BeginningOfEndStepTriggeredAbility( Ability ability = new BeginningOfEndStepTriggeredAbility(new MirrodinBesiegedEffect());
new MirrodinBesiegedEffect()
), new ModeChoiceSourceCondition("Phyrexian"), ruleTrigger2);
ability.addTarget(new TargetOpponent()); ability.addTarget(new TargetOpponent());
this.addAbility(ability); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.PHYREXIAN)));
} }
private MirrodinBesieged(final MirrodinBesieged card) { private MirrodinBesieged(final MirrodinBesieged card) {

View file

@ -2,14 +2,13 @@ package mage.cards.m;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.abilities.triggers.BeginningOfDrawTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.triggers.BeginningOfDrawTriggeredAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
@ -31,17 +30,19 @@ public final class MonasterySiege extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// As Monastery Siege enters the battlefield, choose Khans or Dragons. // As Monastery Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
"As {this} enters, choose Khans or Dragons.", ""));
// * Khans - At the beginning of your draw step, draw an additional card, then discard a card. // * Khans - At the beginning of your draw step, draw an additional card, then discard a card.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfDrawTriggeredAbility(new DrawDiscardControllerEffect(1, 1), false), new BeginningOfDrawTriggeredAbility(
new ModeChoiceSourceCondition("Khans"), new DrawDiscardControllerEffect(1, 1), false
"&bull; Khans &mdash; At the beginning of your draw step, draw an additional card, then discard a card.")); ), ModeChoice.KHANS
)));
// * Dragons - Spells your opponents cast that target you or a permanent you control cost {2} more to cast. // * Dragons - Spells your opponents cast that target you or a permanent you control cost {2} more to cast.
this.addAbility(new SimpleStaticAbility(new MonasterySiegeCostIncreaseEffect())); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new MonasterySiegeCostIncreaseEffect(), ModeChoice.DRAGONS
)));
} }
private MonasterySiege(final MonasterySiege card) { private MonasterySiege(final MonasterySiege card) {
@ -56,11 +57,9 @@ public final class MonasterySiege extends CardImpl {
class MonasterySiegeCostIncreaseEffect extends CostModificationEffectImpl { class MonasterySiegeCostIncreaseEffect extends CostModificationEffectImpl {
private static final ModeChoiceSourceCondition modeDragons = new ModeChoiceSourceCondition("Dragons");
MonasterySiegeCostIncreaseEffect() { MonasterySiegeCostIncreaseEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST);
staticText = "&bull; Dragons &mdash; Spells your opponents cast that target you or a permanent you control cost {2} more to cast"; staticText = "spells your opponents cast that target you or a permanent you control cost {2} more to cast";
} }
private MonasterySiegeCostIncreaseEffect(final MonasterySiegeCostIncreaseEffect effect) { private MonasterySiegeCostIncreaseEffect(final MonasterySiegeCostIncreaseEffect effect) {
@ -75,10 +74,6 @@ class MonasterySiegeCostIncreaseEffect extends CostModificationEffectImpl {
@Override @Override
public boolean applies(Ability abilityToModify, Ability source, Game game) { public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (!modeDragons.apply(game, source)) {
return false;
}
if (!(abilityToModify instanceof SpellAbility)) { if (!(abilityToModify instanceof SpellAbility)) {
return false; return false;
} }

View file

@ -1,54 +1,48 @@
package mage.cards.o; package mage.cards.o;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility;
import mage.abilities.common.ZoneChangeAllTriggeredAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
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.Duration; import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.ModeChoice;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.StaticFilters;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class OutpostSiege extends CardImpl { public final class OutpostSiege extends CardImpl {
private static final String ruleTrigger1 = "&bull Khans &mdash; At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card.";
private static final String ruleTrigger2 = "&bull Dragons &mdash; Whenever a creature you control leaves the battlefield, {this} deals 1 damage to any target.";
public OutpostSiege(UUID ownerId, CardSetInfo setInfo) { public OutpostSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// As Outpost Siege enters the battlefield, choose Khans or Dragons. // As Outpost Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
"As {this} enters, choose Khans or Dragons.", ""));
// * Khans - At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card. // * Khans - At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfUpkeepTriggeredAbility(new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn)), new BeginningOfUpkeepTriggeredAbility(
new ModeChoiceSourceCondition("Khans"), new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn)
ruleTrigger1)); ), ModeChoice.KHANS
)));
// * Dragons - Whenever a creature you control leaves the battlefield, Outpost Siege deals 1 damage to any target. // * Dragons - Whenever a creature you control leaves the battlefield, Outpost Siege deals 1 damage to any target.
Ability ability2 = new ConditionalTriggeredAbility( Ability ability = new LeavesBattlefieldAllTriggeredAbility(
new ZoneChangeAllTriggeredAbility(Zone.BATTLEFIELD, Zone.BATTLEFIELD, null, new DamageTargetEffect(1), new DamageTargetEffect(1), StaticFilters.FILTER_CONTROLLED_A_CREATURE
new FilterControlledCreaturePermanent(), "", false), );
new ModeChoiceSourceCondition("Dragons"), ability.addTarget(new TargetAnyTarget());
ruleTrigger2); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.DRAGONS)));
ability2.addTarget(new TargetAnyTarget());
this.addAbility(ability2);
} }
private OutpostSiege(final OutpostSiege card) { private OutpostSiege(final OutpostSiege card) {

View file

@ -1,55 +1,43 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
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.ModeChoice;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class PalaceSiege extends CardImpl { public final class PalaceSiege extends CardImpl {
private static final String ruleTrigger1 = "&bull Khans &mdash; At the beginning of your upkeep, return target creature card from your graveyard to your hand.";
private static final String ruleTrigger2 = "&bull Dragons &mdash; At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.";
public PalaceSiege(UUID ownerId, CardSetInfo setInfo) { public PalaceSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
// As Palace Siege enters the battlefield, choose Khans or Dragons. // As Palace Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
"As {this} enters, choose Khans or Dragons.", ""));
// * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand. // * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand.
Ability ability1 = new ConditionalTriggeredAbility( Ability ability1 = new BeginningOfUpkeepTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
new BeginningOfUpkeepTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1);
ability1.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE)); ability1.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability1); this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability1, ModeChoice.KHANS)));
// * Dragons - At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life. // * Dragons - At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.
Ability ability2 = new ConditionalTriggeredAbility( Ability ability2 = new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsEffect(2));
new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsEffect(2)), ability2.addEffect(new GainLifeEffect(2).setText("and you gain 2 life"));
new ModeChoiceSourceCondition("Dragons"), this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability2, ModeChoice.DRAGONS)));
ruleTrigger2);
Effect effect = new GainLifeEffect(2);
effect.setText("and you gain 2 life");
ability2.addEffect(effect);
this.addAbility(ability2);
} }

View file

@ -1,23 +1,21 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl; import mage.abilities.costs.CostImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.constants.*;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterNonlandPermanent; import mage.filter.common.FilterNonlandPermanent;
@ -27,6 +25,8 @@ import mage.game.permanent.token.HorrorEnchantmentCreatureToken;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID;
/** /**
* @author Cguy7777 * @author Cguy7777
*/ */
@ -41,28 +41,23 @@ public final class PhenomenonInvestigators extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// As Phenomenon Investigators enters, choose Believe or Doubt. // As Phenomenon Investigators enters, choose Believe or Doubt.
this.addAbility(new AsEntersBattlefieldAbility( this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.BELIEVE, ModeChoice.DOUBT)));
new ChooseModeEffect("Believe or Doubt?", "Believe", "Doubt")));
// * Believe -- Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token. // * Believe -- Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new DiesCreatureTriggeredAbility( new DiesCreatureTriggeredAbility(
new CreateTokenEffect(new HorrorEnchantmentCreatureToken()), new CreateTokenEffect(new HorrorEnchantmentCreatureToken()),
false, false, StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN
StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN), ), ModeChoice.BELIEVE
new ModeChoiceSourceCondition("Believe"), )));
"&bull Believe &mdash; Whenever a nontoken creature you control dies, " +
"create a 2/2 black Horror enchantment creature token."));
// * Doubt -- At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card. // * Doubt -- At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfEndStepTriggeredAbility( new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid(
new DoIfCostPaid(
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),
new PhenomenonInvestigatorsReturnCost())), new PhenomenonInvestigatorsReturnCost()
new ModeChoiceSourceCondition("Doubt"), )), ModeChoice.DOUBT
"&bull Doubt &mdash; At the beginning of your end step, you may return a nonland permanent " + )));
"you own to your hand. If you do, draw a card."));
} }
private PhenomenonInvestigators(final PhenomenonInvestigators card) { private PhenomenonInvestigators(final PhenomenonInvestigators card) {

View file

@ -1,57 +1,44 @@
package mage.cards.r; package mage.cards.r;
import java.util.UUID; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.BecomesTappedTriggeredAbility; import mage.abilities.common.BecomesTappedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
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.ModeChoice;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author fubs * @author fubs
*/ */
public final class RootsOfLife extends CardImpl { public final class RootsOfLife extends CardImpl {
private static final String ruleTrigger1 = "&bull Island &mdash; Whenever an Island an opponent controls becomes tapped, you gain 1 life"; private static final FilterPermanent filter = new FilterLandPermanent("a land of the chosen type an opponent controls");
private static final String ruleTrigger2 = "&bull Swamp &mdash; Whenever a Swamp an opponent controls becomes tapped, you gain 1 life";
private static final FilterPermanent islandFilter = new FilterPermanent("an Island an opponent controls");
private static final FilterPermanent swampFilter = new FilterPermanent("a Swamp an opponent controls");
static { static {
islandFilter.add(SubType.ISLAND.getPredicate()); filter.add(TargetController.OPPONENT.getControllerPredicate());
islandFilter.add(TargetController.OPPONENT.getControllerPredicate()); filter.add(RootsOfLifePredicate.instance);
swampFilter.add(SubType.SWAMP.getPredicate());
swampFilter.add(TargetController.OPPONENT.getControllerPredicate());
} }
public RootsOfLife(UUID ownerId, CardSetInfo setInfo) { public RootsOfLife(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{G}");
// As Roots of Life enters the battlefield, choose Island or Swamp. // As Roots of Life enters the battlefield, choose Island or Swamp.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Island or Swamp?", "Island", "Swamp"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ISLAND, ModeChoice.SWAMP)));
"As {this} enters, choose Island or Swamp.", ""));
// Whenever a land of the chosen type an opponent controls becomes tapped, you gain 1 life. // Whenever a land of the chosen type an opponent controls becomes tapped, you gain 1 life.
// * Island chosen this.addAbility(new BecomesTappedTriggeredAbility(new GainLifeEffect(1), false, filter));
this.addAbility(new ConditionalTriggeredAbility(
new BecomesTappedTriggeredAbility(new GainLifeEffect(1), false, islandFilter),
new ModeChoiceSourceCondition("Island"),
ruleTrigger1));
// * Swamp chosen
this.addAbility(new ConditionalTriggeredAbility(
new BecomesTappedTriggeredAbility(new GainLifeEffect(1), false, swampFilter),
new ModeChoiceSourceCondition("Swamp"),
ruleTrigger2));
} }
private RootsOfLife(final RootsOfLife card) { private RootsOfLife(final RootsOfLife card) {
@ -63,3 +50,18 @@ public final class RootsOfLife extends CardImpl {
return new RootsOfLife(this); return new RootsOfLife(this);
} }
} }
enum RootsOfLifePredicate implements ObjectSourcePlayerPredicate<Permanent> {
instance;
@Override
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
if (ModeChoice.ISLAND.checkMode(game, input.getSource())) {
return input.getObject().hasSubtype(SubType.ISLAND, game);
} else if (ModeChoice.SWAMP.checkMode(game, input.getSource())) {
return input.getObject().hasSubtype(SubType.SWAMP, game);
} else {
return false;
}
}
}

View file

@ -2,18 +2,19 @@ package mage.cards.s;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
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.ModeChoice;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
@ -34,29 +35,21 @@ import java.util.stream.Collectors;
*/ */
public final class StruggleForProjectPurity extends CardImpl { public final class StruggleForProjectPurity extends CardImpl {
private static final String ruleTrigger1 = "&bull Brotherhood &mdash; At the beginning of your upkeep, each opponent draws a card. You draw a card for each card drawn this way.";
private static final String ruleTrigger2 = "&bull Enclave &mdash; Whenever a player attacks you with one or more creatures, that player gets twice that many rad counters.";
public StruggleForProjectPurity(UUID ownerId, CardSetInfo setInfo) { public StruggleForProjectPurity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
// As Struggle for Project Purity enters, choose Brotherhood or Enclave. // As Struggle for Project Purity enters, choose Brotherhood or Enclave.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Brotherhood or Enclave?", "Brotherhood", "Enclave"), null, this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.BROTHERHOOD, ModeChoice.ENCLAVE)));
"As {this} enters, choose Brotherhood or Enclave.", ""));
// * Brotherhood - At the beginning of your upkeep, each opponent draws a card. You draw a card for each card drawn this way. // * Brotherhood - At the beginning of your upkeep, each opponent draws a card. You draw a card for each card drawn this way.
Ability ability = new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfUpkeepTriggeredAbility(new StruggleForProjectDrawEffect()), new BeginningOfUpkeepTriggeredAbility(new StruggleForProjectDrawEffect()), ModeChoice.BROTHERHOOD
new ModeChoiceSourceCondition("Brotherhood"), )));
ruleTrigger1);
this.addAbility(ability);
// * Enclave - Whenever a player attacks you with one or more creatures, that player gets twice that many rad counters. // * Enclave - Whenever a player attacks you with one or more creatures, that player gets twice that many rad counters.
ability = new ConditionalTriggeredAbility( this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new StruggleForProjectRadCountersTriggeredAbility(), new StruggleForProjectRadCountersTriggeredAbility(), ModeChoice.ENCLAVE
new ModeChoiceSourceCondition("Enclave"), )));
ruleTrigger2);
this.addAbility(ability);
} }
private StruggleForProjectPurity(final StruggleForProjectPurity card) { private StruggleForProjectPurity(final StruggleForProjectPurity card) {

View file

@ -0,0 +1,87 @@
package mage.cards.w;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
import mage.abilities.effects.common.replacement.AdditionalTriggersAttackingReplacementEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ModeChoice;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.token.GoblinToken;
import mage.game.permanent.token.Token;
import mage.target.targetpointer.FixedTargets;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WindcragSiege extends CardImpl {
public WindcragSiege(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{W}");
// As this enchantment enters, choose Mardu or Jeskai.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.MARDU, ModeChoice.JESKAI)));
// * Mardu -- If a creature attacking causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new AdditionalTriggersAttackingReplacementEffect(false), ModeChoice.MARDU
)));
// * Jeskai -- At the beginning of your upkeep, create a 1/1 red Goblin creature token. It gains lifelink and haste until end of turn.
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
new BeginningOfUpkeepTriggeredAbility(new WindcragSiegeEffect()), ModeChoice.JESKAI
)));
}
private WindcragSiege(final WindcragSiege card) {
super(card);
}
@Override
public WindcragSiege copy() {
return new WindcragSiege(this);
}
}
class WindcragSiegeEffect extends OneShotEffect {
WindcragSiegeEffect() {
super(Outcome.Benefit);
staticText = "create a 1/1 red Goblin creature token. It gains lifelink and haste until end of turn";
}
private WindcragSiegeEffect(final WindcragSiegeEffect effect) {
super(effect);
}
@Override
public WindcragSiegeEffect copy() {
return new WindcragSiegeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new GoblinToken();
token.putOntoBattlefield(1, game, source);
game.addEffect(new GainAbilityTargetEffect(
LifelinkAbility.getInstance(), Duration.EndOfTurn
).setTargetPointer(new FixedTargets(token, game)), source);
game.addEffect(new GainAbilityTargetEffect(
HasteAbility.getInstance(), Duration.EndOfTurn
).setTargetPointer(new FixedTargets(token, game)), source);
return true;
}
}

View file

@ -1,19 +1,14 @@
package mage.cards.w; package mage.cards.w;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.replacement.AdditionalTriggersAttackingReplacementEffect;
import mage.abilities.keyword.MeleeAbility; import mage.abilities.keyword.MeleeAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Controllable; import mage.constants.SubType;
import mage.game.Game; import mage.constants.SuperType;
import mage.game.events.DefenderAttackedEvent;
import mage.game.events.GameEvent;
import mage.game.events.NumberOfTriggersEvent;
import mage.game.permanent.Permanent;
import java.util.UUID; import java.util.UUID;
@ -35,7 +30,7 @@ public final class WulfgarOfIcewindDale extends CardImpl {
this.addAbility(new MeleeAbility()); this.addAbility(new MeleeAbility());
// If a creature you control attacking would cause a triggered ability of a permanent you control to trigger, that ability triggers an additional time. // If a creature you control attacking would cause a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
this.addAbility(new SimpleStaticAbility(new WulfgarOfIcewindDaleEffect())); this.addAbility(new SimpleStaticAbility(new AdditionalTriggersAttackingReplacementEffect(true)));
} }
private WulfgarOfIcewindDale(final WulfgarOfIcewindDale card) { private WulfgarOfIcewindDale(final WulfgarOfIcewindDale card) {
@ -47,64 +42,3 @@ public final class WulfgarOfIcewindDale extends CardImpl {
return new WulfgarOfIcewindDale(this); return new WulfgarOfIcewindDale(this);
} }
} }
class WulfgarOfIcewindDaleEffect extends ReplacementEffectImpl {
WulfgarOfIcewindDaleEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "if a creature you control attacking causes a triggered ability " +
"of a permanent you control to trigger, that ability triggers an additional time";
}
private WulfgarOfIcewindDaleEffect(final WulfgarOfIcewindDaleEffect effect) {
super(effect);
}
@Override
public WulfgarOfIcewindDaleEffect copy() {
return new WulfgarOfIcewindDaleEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event;
Permanent sourcePermanent = game.getPermanent(numberOfTriggersEvent.getSourceId());
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
return false;
}
GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent();
if (sourceEvent == null) {
return false;
}
switch (sourceEvent.getType()) {
case ATTACKER_DECLARED:
return source.isControlledBy(sourceEvent.getPlayerId());
case DECLARED_ATTACKERS:
return game
.getCombat()
.getAttackers()
.stream()
.map(game::getControllerId)
.anyMatch(source::isControlledBy);
case DEFENDER_ATTACKED:
return ((DefenderAttackedEvent) sourceEvent)
.getAttackers(game)
.stream()
.map(Controllable::getControllerId)
.anyMatch(source::isControlledBy);
}
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(event.getAmount() + 1);
return false;
}
}

View file

@ -274,6 +274,7 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Whirlwing Stormbrood", 234, Rarity.UNCOMMON, mage.cards.w.WhirlwingStormbrood.class)); cards.add(new SetCardInfo("Whirlwing Stormbrood", 234, Rarity.UNCOMMON, mage.cards.w.WhirlwingStormbrood.class));
cards.add(new SetCardInfo("Wild Ride", 132, Rarity.COMMON, mage.cards.w.WildRide.class)); cards.add(new SetCardInfo("Wild Ride", 132, Rarity.COMMON, mage.cards.w.WildRide.class));
cards.add(new SetCardInfo("Wind-Scarred Crag", 271, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 271, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
cards.add(new SetCardInfo("Windcrag Siege", 235, Rarity.RARE, mage.cards.w.WindcragSiege.class));
cards.add(new SetCardInfo("Wingblade Disciple", 65, Rarity.UNCOMMON, mage.cards.w.WingbladeDisciple.class)); cards.add(new SetCardInfo("Wingblade Disciple", 65, Rarity.UNCOMMON, mage.cards.w.WingbladeDisciple.class));
cards.add(new SetCardInfo("Wingspan Stride", 66, Rarity.COMMON, mage.cards.w.WingspanStride.class)); cards.add(new SetCardInfo("Wingspan Stride", 66, Rarity.COMMON, mage.cards.w.WingspanStride.class));
cards.add(new SetCardInfo("Winternight Stories", 67, Rarity.RARE, mage.cards.w.WinternightStories.class)); cards.add(new SetCardInfo("Winternight Stories", 67, Rarity.RARE, mage.cards.w.WinternightStories.class));

View file

@ -1,10 +1,6 @@
package org.mage.test.cards.single.c19; package org.mage.test.cards.single.c19;
import mage.abilities.effects.common.continuous.PlayerCanOnlyAttackInDirectionRestrictionEffect; import mage.constants.*;
import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.game.FreeForAll; import mage.game.FreeForAll;
import mage.game.Game; import mage.game.Game;
import mage.game.GameException; import mage.game.GameException;
@ -63,7 +59,7 @@ public class PramikonSkyRampartTest extends CardTestMultiPlayerBase {
addCard(Zone.BATTLEFIELD, playerD, devil); addCard(Zone.BATTLEFIELD, playerD, devil);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon);
setChoice(playerA, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_LEFT); setChoice(playerA, ModeChoice.LEFT.toString());
// A has pramikon, and chose left. // A has pramikon, and chose left.
// //
@ -128,7 +124,7 @@ public class PramikonSkyRampartTest extends CardTestMultiPlayerBase {
addCard(Zone.BATTLEFIELD, playerD, devil); addCard(Zone.BATTLEFIELD, playerD, devil);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon);
setChoice(playerA, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_RIGHT); setChoice(playerA, ModeChoice.RIGHT.toString());
// A has pramikon, and chose right. // A has pramikon, and chose right.
// //
@ -197,10 +193,10 @@ public class PramikonSkyRampartTest extends CardTestMultiPlayerBase {
addCard(Zone.BATTLEFIELD, playerD, devil); addCard(Zone.BATTLEFIELD, playerD, devil);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon);
setChoice(playerA, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_RIGHT); setChoice(playerA, ModeChoice.RIGHT.toString());
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, pramikon); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, pramikon);
setChoice(playerD, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_LEFT); setChoice(playerD, ModeChoice.LEFT.toString());
// A has pramikon, and chose right. // A has pramikon, and chose right.
// D has pramikon, and chose left. // D has pramikon, and chose left.
@ -270,10 +266,10 @@ public class PramikonSkyRampartTest extends CardTestMultiPlayerBase {
addCard(Zone.BATTLEFIELD, playerD, devil); addCard(Zone.BATTLEFIELD, playerD, devil);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pramikon);
setChoice(playerA, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_LEFT); setChoice(playerA, ModeChoice.LEFT.toString());
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, pramikon); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, pramikon);
setChoice(playerD, PlayerCanOnlyAttackInDirectionRestrictionEffect.ALLOW_ATTACKING_RIGHT); setChoice(playerD, ModeChoice.RIGHT.toString());
// A has pramikon, and chose left. // A has pramikon, and chose left.
// D has pramikon, and chose right. // D has pramikon, and chose right.

View file

@ -1,26 +0,0 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.game.Game;
/**
*
* @author LevelX2
*/
public class ModeChoiceSourceCondition implements Condition {
private final String mode;
public ModeChoiceSourceCondition(String mode) {
this.mode = mode;
}
@Override
public boolean apply(Game game, Ability source) {
String chosenMode = (String) game.getState().getValue(source.getSourceId() + "_modeChoice");
return chosenMode != null && chosenMode.equals(mode);
}
}

View file

@ -1,39 +1,41 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.ModeChoice;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author LevelX2 * @author LevelX2
*/ */
public class ChooseModeEffect extends OneShotEffect { public class ChooseModeEffect extends OneShotEffect {
protected final List<String> modes = new ArrayList<>(); protected final List<ModeChoice> modes = new ArrayList<>();
protected final String choiceMessage; protected final String message;
public ChooseModeEffect(String choiceMessage, String... modes) { public ChooseModeEffect(ModeChoice... modes) {
super(Outcome.Neutral); super(Outcome.Neutral);
this.choiceMessage = choiceMessage;
this.modes.addAll(Arrays.asList(modes)); this.modes.addAll(Arrays.asList(modes));
this.staticText = setText(); this.message = makeMessage(this.modes);
this.staticText = "choose " + this.message;
} }
protected ChooseModeEffect(final ChooseModeEffect effect) { protected ChooseModeEffect(final ChooseModeEffect effect) {
super(effect); super(effect);
this.modes.addAll(effect.modes); this.modes.addAll(effect.modes);
this.choiceMessage = effect.choiceMessage; this.message = effect.message;
} }
@Override @Override
@ -48,34 +50,27 @@ public class ChooseModeEffect extends OneShotEffect {
if (sourcePermanent == null) { if (sourcePermanent == null) {
sourcePermanent = game.getPermanentEntering(source.getSourceId()); sourcePermanent = game.getPermanentEntering(source.getSourceId());
} }
if (controller != null && sourcePermanent != null) { if (controller == null || sourcePermanent == null) {
Choice choice = new ChoiceImpl(true); return false;
choice.setMessage(choiceMessage + CardUtil.getSourceLogName(game, source));
choice.getChoices().addAll(modes);
if (controller.choose(Outcome.Neutral, choice, game)) {
if (!game.isSimulation()) {
game.informPlayers(sourcePermanent.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice());
} }
Choice choice = new ChoiceImpl(true);
choice.setMessage(message + "? (" + CardUtil.getSourceLogName(game, source) + ')');
choice.getChoices().addAll(modes.stream().map(ModeChoice::toString).collect(Collectors.toList()));
if (!controller.choose(Outcome.Neutral, choice, game)) {
return false;
}
game.informPlayers(sourcePermanent.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice());
game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice()); game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice());
sourcePermanent.addInfo("_modeChoice", "<font color = 'blue'>Chosen mode: " + choice.getChoice() + "</font>", game); sourcePermanent.addInfo("_modeChoice", "<font color = 'blue'>Chosen mode: " + choice.getChoice() + "</font>", game);
return true; return true;
} }
}
return false;
}
private String setText() { private static String makeMessage(List<ModeChoice> modeChoices) {
StringBuilder sb = new StringBuilder("choose "); return CardUtil.concatWithOr(
int count = 0; modeChoices
for (String choice : modes) { .stream()
count++; .map(ModeChoice::toString)
sb.append(choice); .collect(Collectors.toList())
if (count + 1 < modes.size()) { );
sb.append(", ");
} else if (count < modes.size()) {
sb.append(" or ");
}
}
return sb.toString();
} }
} }

View file

@ -63,7 +63,7 @@ public class PermanentsEnterBattlefieldTappedEffect extends ReplacementEffectImp
return staticText; return staticText;
} }
return filter.getMessage() return filter.getMessage()
+ " enter tapped" + " enter" + (filter.getMessage().startsWith("each") ? "s" : "")
+ (duration == Duration.EndOfTurn ? " this turn" : ""); + " tapped" + (duration == Duration.EndOfTurn ? " this turn" : "");
} }
} }

View file

@ -0,0 +1,52 @@
package mage.abilities.effects.common.continuous;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
* @author TheElk801
*/
public class GainAnchorWordAbilitySourceEffect extends ContinuousEffectImpl {
private final Ability ability;
private final ModeChoice modeChoice;
public GainAnchorWordAbilitySourceEffect(Effect effect, ModeChoice modeChoice) {
this(new SimpleStaticAbility(effect), modeChoice);
}
public GainAnchorWordAbilitySourceEffect(Ability ability, ModeChoice modeChoice) {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.staticText = "&bull " + modeChoice + " &mdash; " + ability.getRule();
this.ability = ability;
this.modeChoice = modeChoice;
this.ability.setRuleVisible(false);
this.generateGainAbilityDependencies(ability, null);
}
private GainAnchorWordAbilitySourceEffect(final GainAnchorWordAbilitySourceEffect effect) {
super(effect);
this.modeChoice = effect.modeChoice;
this.ability = effect.ability;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || !modeChoice.checkMode(game, source)) {
return false;
}
permanent.addAbility(ability, source.getSourceId(), game);
return true;
}
@Override
public GainAnchorWordAbilitySourceEffect copy() {
return new GainAnchorWordAbilitySourceEffect(this);
}
}

View file

@ -6,6 +6,7 @@ import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.ChooseModeEffect; import mage.abilities.effects.common.ChooseModeEffect;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.ModeChoice;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -19,9 +20,6 @@ import java.util.UUID;
*/ */
public class PlayerCanOnlyAttackInDirectionRestrictionEffect extends RestrictionEffect { public class PlayerCanOnlyAttackInDirectionRestrictionEffect extends RestrictionEffect {
public static final String ALLOW_ATTACKING_LEFT = "Allow attacking left";
public static final String ALLOW_ATTACKING_RIGHT = "Allow attacking right";
public PlayerCanOnlyAttackInDirectionRestrictionEffect(Duration duration, String directionText) { public PlayerCanOnlyAttackInDirectionRestrictionEffect(Duration duration, String directionText) {
super(duration, Outcome.Neutral); super(duration, Outcome.Neutral);
staticText = duration + (duration.toString().isEmpty() ? "" : ", ") staticText = duration + (duration.toString().isEmpty() ? "" : ", ")
@ -39,10 +37,7 @@ public class PlayerCanOnlyAttackInDirectionRestrictionEffect extends Restriction
} }
public static Effect choiceEffect() { public static Effect choiceEffect() {
return new ChooseModeEffect( return new ChooseModeEffect(ModeChoice.LEFT, ModeChoice.RIGHT);
"Choose a direction to allow attacking in.",
ALLOW_ATTACKING_LEFT, ALLOW_ATTACKING_RIGHT
).setText("choose left or right");
} }
@Override @Override
@ -55,10 +50,13 @@ public class PlayerCanOnlyAttackInDirectionRestrictionEffect extends Restriction
if (defenderId == null) { if (defenderId == null) {
return true; return true;
} }
boolean left;
String allowedDirection = (String) game.getState().getValue(source.getSourceId() + "_modeChoice"); if (ModeChoice.LEFT.checkMode(game, source)) {
if (allowedDirection == null) { left = true;
return true; // If no choice was made, the ability has no effect. } else if (ModeChoice.RIGHT.checkMode(game, source)) {
left = false;
} else {
return false; // If no choice was made, the ability has no effect.
} }
Player playerAttacking = game.getPlayer(attacker.getControllerId()); Player playerAttacking = game.getPlayer(attacker.getControllerId());
@ -83,18 +81,7 @@ public class PlayerCanOnlyAttackInDirectionRestrictionEffect extends Restriction
} }
PlayerList playerList = game.getState().getPlayerList(playerAttacking.getId()); PlayerList playerList = game.getState().getPlayerList(playerAttacking.getId());
if (allowedDirection.equals(ALLOW_ATTACKING_LEFT) return (!left || playerList.getNext().equals(playerDefending.getId()))
&& !playerList.getNext().equals(playerDefending.getId())) { && (left || playerList.getPrevious().equals(playerDefending.getId()));
// the defender is not the player to the left
return false;
} }
if (allowedDirection.equals(ALLOW_ATTACKING_RIGHT)
&& !playerList.getPrevious().equals(playerDefending.getId())) {
// the defender is not the player to the right
return false;
}
return true;
}
} }

View file

@ -0,0 +1,80 @@
package mage.abilities.effects.common.replacement;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.events.DefenderAttackedEvent;
import mage.game.events.GameEvent;
import mage.game.events.NumberOfTriggersEvent;
import mage.game.permanent.Permanent;
/**
* @author TheElk801
*/
public class AdditionalTriggersAttackingReplacementEffect extends ReplacementEffectImpl {
private final boolean onlyControlled;
public AdditionalTriggersAttackingReplacementEffect(boolean onlyControlled) {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
this.onlyControlled = onlyControlled;
staticText = "if a creature " + (onlyControlled ? "you control " : "") + "attacking causes a triggered ability " +
"of a permanent you control to trigger, that ability triggers an additional time";
}
private AdditionalTriggersAttackingReplacementEffect(final AdditionalTriggersAttackingReplacementEffect effect) {
super(effect);
this.onlyControlled = effect.onlyControlled;
}
@Override
public AdditionalTriggersAttackingReplacementEffect copy() {
return new AdditionalTriggersAttackingReplacementEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event;
Permanent sourcePermanent = game.getPermanent(numberOfTriggersEvent.getSourceId());
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
return false;
}
GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent();
if (sourceEvent == null) {
return false;
}
switch (sourceEvent.getType()) {
case ATTACKER_DECLARED:
return !onlyControlled || source.isControlledBy(sourceEvent.getPlayerId());
case DECLARED_ATTACKERS:
return !onlyControlled || game
.getCombat()
.getAttackers()
.stream()
.map(game::getControllerId)
.anyMatch(source::isControlledBy);
case DEFENDER_ATTACKED:
return !onlyControlled || ((DefenderAttackedEvent) sourceEvent)
.getAttackers(game)
.stream()
.map(Controllable::getControllerId)
.anyMatch(source::isControlledBy);
}
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(event.getAmount() + 1);
return false;
}
}

View file

@ -0,0 +1,75 @@
package mage.constants;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.game.Game;
import java.util.Objects;
public enum ModeChoice {
KHANS("Khans"),
DRAGONS("Dragons"),
MARDU("Mardu"),
TEMUR("Temur"),
ABZAN("Abzan"),
JESKAI("Jeskai"),
SULTAI("Sultai"),
MIRRAN("Mirran"),
PHYREXIAN("Phyrexian "),
ODD("odd"),
EVEN("even"),
BELIEVE("Believe"),
DOUBT("Doubt"),
NCR("NCR"),
LEGION("Legion"),
BROTHERHOOD("Brotherhood"),
ENCLAVE("Enclave"),
ISLAND("Island"),
SWAMP("Swamp"),
LEFT("left"),
RIGHT("right");
private static class ModeChoiceCondition implements Condition {
private final ModeChoice modeChoice;
ModeChoiceCondition(ModeChoice modeChoice) {
this.modeChoice = modeChoice;
}
@Override
public boolean apply(Game game, Ability source) {
return modeChoice.checkMode(game, source);
}
}
private final String name;
private final ModeChoiceCondition condition;
ModeChoice(String name) {
this.name = name;
this.condition = new ModeChoiceCondition(this);
}
@Override
public String toString() {
return name;
}
public ModeChoiceCondition getCondition() {
return condition;
}
public boolean checkMode(Game game, Ability source) {
return Objects.equals(game.getState().getValue(source.getSourceId() + "_modeChoice"), name);
}
}