diff --git a/Mage.Sets/src/mage/cards/h/HiddenAncients.java b/Mage.Sets/src/mage/cards/h/HiddenAncients.java index 2872a8136b0..693e2c71a84 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenAncients.java +++ b/Mage.Sets/src/mage/cards/h/HiddenAncients.java @@ -1,9 +1,7 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,7 +9,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -20,15 +18,18 @@ import java.util.UUID; */ public final class HiddenAncients extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition("{this} is an enchantment", StaticFilters.FILTER_PERMANENT_ENCHANTMENT); - public HiddenAncients(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); // When an opponent casts an enchantment spell, if Hidden Ancients is an enchantment, Hidden Ancients becomes a 5/5 Treefolk creature. this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new HiddenAncientsTreefolkToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_AN_ENCHANTMENT, false).withInterveningIf(condition).setTriggerPhrase("When an opponent casts an enchantment spell, ")); + new CreatureToken( + 5, 5, "5/5 Treefolk creature", SubType.TREEFOLK + ), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_AN_ENCHANTMENT, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts an enchantment spell, ")); } private HiddenAncients(final HiddenAncients card) { @@ -40,22 +41,3 @@ public final class HiddenAncients extends CardImpl { return new HiddenAncients(this); } } - -class HiddenAncientsTreefolkToken extends TokenImpl { - - public HiddenAncientsTreefolkToken() { - super("Treefolk", "5/5 Treefolk creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.TREEFOLK); - power = new MageInt(5); - toughness = new MageInt(5); - } - - private HiddenAncientsTreefolkToken(final HiddenAncientsTreefolkToken token) { - super(token); - } - - public HiddenAncientsTreefolkToken copy() { - return new HiddenAncientsTreefolkToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HiddenGibbons.java b/Mage.Sets/src/mage/cards/h/HiddenGibbons.java index 275ad6f8052..2fd9309b0d0 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenGibbons.java +++ b/Mage.Sets/src/mage/cards/h/HiddenGibbons.java @@ -1,9 +1,7 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,8 +9,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.FilterSpell; -import mage.filter.StaticFilters; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -27,15 +24,17 @@ public final class HiddenGibbons extends CardImpl { filter.add(CardType.INSTANT.getPredicate()); } - private static final Condition condition = new SourceMatchesFilterCondition("{this} is an enchantment", StaticFilters.FILTER_PERMANENT_ENCHANTMENT); - public HiddenGibbons(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); // When an opponent casts an instant spell, if Hidden Gibbons is an enchantment, Hidden Gibbons becomes a 4/4 Ape creature. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect(new HiddenGibbonsApe(), null, Duration.WhileOnBattlefield), filter, false - ).withInterveningIf(condition).setTriggerPhrase("When an opponent casts an instant spell, ")); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken(4, 4, "4/4 Ape creature", SubType.APE), + null, Duration.WhileOnBattlefield + ), filter, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts an instant spell, ")); } private HiddenGibbons(final HiddenGibbons card) { @@ -47,22 +46,3 @@ public final class HiddenGibbons extends CardImpl { return new HiddenGibbons(this); } } - -class HiddenGibbonsApe extends TokenImpl { - - public HiddenGibbonsApe() { - super("Ape", "4/4 Ape creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.APE); - power = new MageInt(4); - toughness = new MageInt(4); - } - - private HiddenGibbonsApe(final HiddenGibbonsApe token) { - super(token); - } - - public HiddenGibbonsApe copy() { - return new HiddenGibbonsApe(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HiddenGuerrillas.java b/Mage.Sets/src/mage/cards/h/HiddenGuerrillas.java index cfd300b8242..df33a20de37 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenGuerrillas.java +++ b/Mage.Sets/src/mage/cards/h/HiddenGuerrillas.java @@ -1,9 +1,7 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; @@ -12,7 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -21,15 +19,18 @@ import java.util.UUID; */ public final class HiddenGuerrillas extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition("{this} is an enchantment", StaticFilters.FILTER_PERMANENT_ENCHANTMENT); - public HiddenGuerrillas(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); // When an opponent casts an artifact spell, if Hidden Guerrillas is an enchantment, Hidden Guerrillas becomes a 5/3 Soldier creature with trample. this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new HiddenGuerrillasSoldier(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_AN_ARTIFACT, false).withInterveningIf(condition).setTriggerPhrase("When an opponent casts an artifact spell, ")); + new CreatureToken( + 5, 3, "5/3 Soldier creature with trample", SubType.SOLDIER + ).withAbility(TrampleAbility.getInstance()), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_AN_ARTIFACT, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts an artifact spell, ")); } private HiddenGuerrillas(final HiddenGuerrillas card) { @@ -41,23 +42,3 @@ public final class HiddenGuerrillas extends CardImpl { return new HiddenGuerrillas(this); } } - -class HiddenGuerrillasSoldier extends TokenImpl { - - public HiddenGuerrillasSoldier() { - super("Soldier", "5/3 Soldier creature with trample"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SOLDIER); - power = new MageInt(5); - toughness = new MageInt(3); - this.addAbility(TrampleAbility.getInstance()); - } - - private HiddenGuerrillasSoldier(final HiddenGuerrillasSoldier token) { - super(token); - } - - public HiddenGuerrillasSoldier copy() { - return new HiddenGuerrillasSoldier(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HiddenHerd.java b/Mage.Sets/src/mage/cards/h/HiddenHerd.java index a8eb6640161..643b6a624a4 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenHerd.java +++ b/Mage.Sets/src/mage/cards/h/HiddenHerd.java @@ -1,7 +1,7 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -12,9 +12,8 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; -import java.util.Optional; import java.util.UUID; /** @@ -42,7 +41,13 @@ public final class HiddenHerd extends CardImpl { class HiddenHerdAbility extends TriggeredAbilityImpl { public HiddenHerdAbility() { - super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new HiddenHerdBeast(), null, Duration.WhileOnBattlefield), false); + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect( + new CreatureToken(3, 3, "3/3 Beast creature", SubType.BEAST), + null, Duration.WhileOnBattlefield + ), false); + this.withInterveningIf(SourceIsEnchantmentCondition.instance); + this.withRuleTextReplacement(true); + this.setTriggerPhrase("When an opponent plays a nonbasic land, "); } private HiddenHerdAbility(final HiddenHerdAbility ability) { @@ -62,38 +67,6 @@ class HiddenHerdAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return game.getOpponents(controllerId).contains(event.getPlayerId()) && !land.isBasic(game); - } - - @Override - public boolean checkInterveningIfClause(Game game) { - return Optional - .ofNullable(getSourcePermanentIfItStillExists(game)) - .filter(permanent -> permanent.isEnchantment(game)) - .isPresent(); - } - - @Override - public String getRule() { - return "When an opponent plays a nonbasic land, if {this} is an enchantment, {this} becomes a 3/3 Beast creature."; - } -} - -class HiddenHerdBeast extends TokenImpl { - - public HiddenHerdBeast() { - super("Beast", "3/3 Beast creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.BEAST); - power = new MageInt(3); - toughness = new MageInt(3); - } - - private HiddenHerdBeast(final HiddenHerdBeast token) { - super(token); - } - - public HiddenHerdBeast copy() { - return new HiddenHerdBeast(this); + return land != null && game.getOpponents(getControllerId()).contains(event.getPlayerId()) && !land.isBasic(game); } } diff --git a/Mage.Sets/src/mage/cards/h/HiddenPredators.java b/Mage.Sets/src/mage/cards/h/HiddenPredators.java index 6a2027e90fe..474268107a1 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenPredators.java +++ b/Mage.Sets/src/mage/cards/h/HiddenPredators.java @@ -1,7 +1,7 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.StateTriggeredAbility; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -10,7 +10,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -46,9 +46,10 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { } public HiddenPredatorsStateTriggeredAbility() { - super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new HiddenPredatorsToken(), null, Duration.Custom)); - this.withRuleTextReplacement(false); - setTriggerPhrase("When an opponent controls a creature with power 4 or greater, if {this} is an enchantment, "); + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new CreatureToken(4, 4, "4/4 Beast creature", SubType.BEAST), null, Duration.Custom)); + this.withInterveningIf(SourceIsEnchantmentCondition.instance); + this.withRuleTextReplacement(true); + this.setTriggerPhrase("When an opponent controls a creature with power 4 or greater, "); } private HiddenPredatorsStateTriggeredAbility(final HiddenPredatorsStateTriggeredAbility ability) { @@ -64,32 +65,4 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { return !game.getBattlefield().getActivePermanents(filter, game.getControllerId(getSourceId()), game).isEmpty(); } - - @Override - public boolean checkInterveningIfClause(Game game) { - if (getSourcePermanentIfItStillExists(game) != null) { - return getSourcePermanentIfItStillExists(game).isEnchantment(game); - } - return false; - } - -} - -class HiddenPredatorsToken extends TokenImpl { - - public HiddenPredatorsToken() { - super("Beast", "4/4 Beast creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.BEAST); - power = new MageInt(4); - toughness = new MageInt(4); - } - - private HiddenPredatorsToken(final HiddenPredatorsToken token) { - super(token); - } - - public HiddenPredatorsToken copy() { - return new HiddenPredatorsToken(this); - } } diff --git a/Mage.Sets/src/mage/cards/h/HiddenSpider.java b/Mage.Sets/src/mage/cards/h/HiddenSpider.java index 3f350ddc9e8..4152cf08d32 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenSpider.java +++ b/Mage.Sets/src/mage/cards/h/HiddenSpider.java @@ -1,10 +1,7 @@ - package mage.cards.h; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReachAbility; @@ -13,10 +10,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureSpell; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -31,15 +27,18 @@ public final class HiddenSpider extends CardImpl { filter.add(new AbilityPredicate(FlyingAbility.class)); } - private static final Condition condition = new SourceMatchesFilterCondition("{this} is an enchantment", StaticFilters.FILTER_PERMANENT_ENCHANTMENT); - public HiddenSpider(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); // When an opponent casts a creature spell with flying, if Hidden Spider is an enchantment, Hidden Spider becomes a 3/5 Spider creature with reach. this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new HiddenSpiderToken(), null, Duration.WhileOnBattlefield - ), filter, false).withInterveningIf(condition).setTriggerPhrase("When an opponent casts a creature spell with flying, ")); + new CreatureToken( + 3, 5, "3/5 Spider creature with reach", SubType.SPIDER + ).withAbility(ReachAbility.getInstance()), null, Duration.WhileOnBattlefield + ), filter, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a creature spell with flying, ")); } private HiddenSpider(final HiddenSpider card) { @@ -51,23 +50,3 @@ public final class HiddenSpider extends CardImpl { return new HiddenSpider(this); } } - -class HiddenSpiderToken extends TokenImpl { - - public HiddenSpiderToken() { - super("Spider", "3/5 Spider creature with reach"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SPIDER); - power = new MageInt(3); - toughness = new MageInt(5); - this.addAbility(ReachAbility.getInstance()); - } - - private HiddenSpiderToken(final HiddenSpiderToken token) { - super(token); - } - - public HiddenSpiderToken copy() { - return new HiddenSpiderToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HiddenStag.java b/Mage.Sets/src/mage/cards/h/HiddenStag.java index f710094fd3b..7b4764c98e1 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenStag.java +++ b/Mage.Sets/src/mage/cards/h/HiddenStag.java @@ -4,6 +4,7 @@ import mage.MageInt; import mage.abilities.common.ControllerPlaysLandTriggeredAbility; import mage.abilities.common.OpponentPlaysLandTriggeredAbility; import mage.abilities.condition.Condition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BecomesEnchantmentSourceEffect; @@ -15,6 +16,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -23,24 +25,24 @@ import java.util.UUID; */ public final class HiddenStag extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition("{this} is an enchantment", StaticFilters.FILTER_PERMANENT_ENCHANTMENT); - private static final Condition condition2 = new SourceMatchesFilterCondition("{this} is a creature", StaticFilters.FILTER_PERMANENT_CREATURE); + private static final Condition condition = new SourceMatchesFilterCondition( + "this permanent is a creature", StaticFilters.FILTER_PERMANENT_CREATURE + ); public HiddenStag(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); // Whenever an opponent plays a land, if Hidden Stag is an enchantment, Hidden Stag becomes a 3/2 Elk Beast creature. - this.addAbility(new OpponentPlaysLandTriggeredAbility( - Zone.BATTLEFIELD, - new BecomesCreatureSourceEffect( - new ElkBeastToken(), null, Duration.WhileOnBattlefield - ), false - ).withInterveningIf(condition)); + this.addAbility(new OpponentPlaysLandTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 3, 2, "3/2 Elk Beast creature", SubType.ELK, SubType.BEAST + ), null, Duration.WhileOnBattlefield + ), false).withInterveningIf(SourceIsEnchantmentCondition.instance).withRuleTextReplacement(true)); // Whenever you play a land, if Hidden Stag is a creature, Hidden Stag becomes an enchantment. this.addAbility(new ControllerPlaysLandTriggeredAbility( Zone.BATTLEFIELD, new BecomesEnchantmentSourceEffect(), false - ).withInterveningIf(condition2)); + ).withInterveningIf(condition).withRuleTextReplacement(true)); } private HiddenStag(final HiddenStag card) { diff --git a/Mage.Sets/src/mage/cards/l/LurkingJackals.java b/Mage.Sets/src/mage/cards/l/LurkingJackals.java index e10149b40a0..d7022a2c54d 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingJackals.java +++ b/Mage.Sets/src/mage/cards/l/LurkingJackals.java @@ -1,7 +1,7 @@ package mage.cards.l; -import mage.MageInt; import mage.abilities.StateTriggeredAbility; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,7 +11,8 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; import java.util.UUID; @@ -40,9 +41,12 @@ public final class LurkingJackals extends CardImpl { class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { public LurkingJackalsStateTriggeredAbility() { - super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new LurkingJackalsToken(), null, Duration.Custom)); - setTriggerPhrase("When an opponent has 10 or less life, if {this} is an enchantment, "); + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new CreatureToken( + 3, 2, "3/2 Jackal creature", SubType.JACKAL + ), null, Duration.Custom)); + this.withInterveningIf(SourceIsEnchantmentCondition.instance); this.withRuleTextReplacement(true); + this.setTriggerPhrase("When an opponent has 10 or less life, "); } private LurkingJackalsStateTriggeredAbility(final LurkingJackalsStateTriggeredAbility ability) { @@ -56,42 +60,11 @@ class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getOpponents(getControllerId()) != null) { - for (UUID opponentId : game.getOpponents(getControllerId())) { - if (game.getPlayer(opponentId).getLife() <= 10) { - return true; - } - } - } - return false; - } - - @Override - public boolean checkInterveningIfClause(Game game) { - if (getSourcePermanentIfItStillExists(game) != null) { - return getSourcePermanentIfItStillExists(game).isEnchantment(game); - } - return false; - } - -} - -class LurkingJackalsToken extends TokenImpl { - - public LurkingJackalsToken() { - super("Dog", "3/2 Jackal creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.JACKAL); - power = new MageInt(3); - toughness = new MageInt(2); - } - - private LurkingJackalsToken(final LurkingJackalsToken token) { - super(token); - } - - @Override - public LurkingJackalsToken copy() { - return new LurkingJackalsToken(this); + return game + .getOpponents(getControllerId()) + .stream() + .map(game::getPlayer) + .mapToInt(Player::getLife) + .anyMatch(x -> x <= 10); } } diff --git a/Mage.Sets/src/mage/cards/l/LurkingSkirge.java b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java index 654264e37be..0dc66fc1257 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingSkirge.java +++ b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java @@ -1,9 +1,7 @@ package mage.cards.l; -import mage.MageInt; import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -13,8 +11,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -29,15 +26,17 @@ public final class LurkingSkirge extends CardImpl { filter.add(TargetController.OPPONENT.getOwnerPredicate()); } - private static final Condition condition = new SourceMatchesFilterCondition(new FilterEnchantmentPermanent("{this} is an enchantment")); - public LurkingSkirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); // When a creature is put into an opponent's graveyard from the battlefield, if Lurking Skirge is an enchantment, Lurking Skirge becomes a 3/2 Imp creature with flying. this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new BecomesCreatureSourceEffect( - new LurkingSkirgeToken(), null, Duration.WhileOnBattlefield - ), false, filter, false).withInterveningIf(condition) + new CreatureToken( + 3, 2, "3/2 Phyrexian Imp creature with flying", SubType.PHYREXIAN, SubType.IMP + ).withAbility(FlyingAbility.getInstance()), null, Duration.WhileOnBattlefield + ), false, filter, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) .setTriggerPhrase("When a creature is put into an opponent's graveyard from the battlefield, ")); } @@ -50,24 +49,3 @@ public final class LurkingSkirge extends CardImpl { return new LurkingSkirge(this); } } - -class LurkingSkirgeToken extends TokenImpl { - - public LurkingSkirgeToken() { - super("Phyrexian Imp", "3/2 Phyrexian Imp with flying."); - cardType.add(CardType.CREATURE); - subtype.add(SubType.PHYREXIAN); - subtype.add(SubType.IMP); - power = new MageInt(3); - toughness = new MageInt(2); - this.addAbility(FlyingAbility.getInstance()); - } - - private LurkingSkirgeToken(final LurkingSkirgeToken token) { - super(token); - } - - public LurkingSkirgeToken copy() { - return new LurkingSkirgeToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java index e3e580eb5d3..7f52f026c94 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java +++ b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java @@ -1,10 +1,8 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BecomesEnchantmentSourceEffect; @@ -14,8 +12,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -24,22 +21,18 @@ import java.util.UUID; */ public final class OpalAcrolith extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalAcrolith(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature. this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalAcrolithToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + new BecomesCreatureSourceEffect(new CreatureToken( + 2, 4, "2/4 Soldier creature", SubType.SOLDIER + ), null, Duration.WhileOnBattlefield), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(SourceIsEnchantmentCondition.instance).withRuleTextReplacement(true)); // {0}: Opal Acrolith becomes an enchantment. - this.addAbility(new SimpleActivatedAbility(new BecomesEnchantmentSourceEffect(), new ManaCostsImpl<>("{0}"))); + this.addAbility(new SimpleActivatedAbility(new BecomesEnchantmentSourceEffect().setText("this permanent becomes an enchantment"), new ManaCostsImpl<>("{0}"))); } private OpalAcrolith(final OpalAcrolith card) { @@ -51,22 +44,3 @@ public final class OpalAcrolith extends CardImpl { return new OpalAcrolith(this); } } - -class OpalAcrolithToken extends TokenImpl { - - public OpalAcrolithToken() { - super("Soldier", "2/4 Soldier creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SOLDIER); - power = new MageInt(2); - toughness = new MageInt(4); - } - - private OpalAcrolithToken(final OpalAcrolithToken token) { - super(token); - } - - public OpalAcrolithToken copy() { - return new OpalAcrolithToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalArchangel.java b/Mage.Sets/src/mage/cards/o/OpalArchangel.java index 90924a0154c..7e82d75e61b 100644 --- a/Mage.Sets/src/mage/cards/o/OpalArchangel.java +++ b/Mage.Sets/src/mage/cards/o/OpalArchangel.java @@ -1,9 +1,7 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; @@ -13,8 +11,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -23,19 +20,19 @@ import java.util.UUID; */ public final class OpalArchangel extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalArchangel(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); // When an opponent casts a creature spell, if Opal Archangel is an enchantment, Opal Archangel becomes a 5/5 Angel creature with flying and vigilance. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalArchangelToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 5, 5, "5/5 Angel creature with flying and vigilance", SubType.ANGEL + ).withAbility(FlyingAbility.getInstance()).withAbility(VigilanceAbility.getInstance()), + null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalArchangel(final OpalArchangel card) { @@ -47,24 +44,3 @@ public final class OpalArchangel extends CardImpl { return new OpalArchangel(this); } } - -class OpalArchangelToken extends TokenImpl { - - public OpalArchangelToken() { - super("Angel", "5/5 Angel creature with flying and vigilance"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.ANGEL); - power = new MageInt(5); - toughness = new MageInt(5); - this.addAbility(FlyingAbility.getInstance()); - this.addAbility(VigilanceAbility.getInstance()); - } - - private OpalArchangelToken(final OpalArchangelToken token) { - super(token); - } - - public OpalArchangelToken copy() { - return new OpalArchangelToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalAvenger.java b/Mage.Sets/src/mage/cards/o/OpalAvenger.java index 812059959bf..5f1f3bc6f02 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAvenger.java +++ b/Mage.Sets/src/mage/cards/o/OpalAvenger.java @@ -1,7 +1,7 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.StateTriggeredAbility; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,8 +11,10 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; +import java.util.Optional; import java.util.UUID; /** @@ -40,9 +42,12 @@ public final class OpalAvenger extends CardImpl { class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility { OpalAvengerStateTriggeredAbility() { - super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new OpalAvengerToken(), null, Duration.Custom)); - this.withRuleTextReplacement(false); - setTriggerPhrase("When you have 10 or less life, if {this} is an enchantment, "); + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect( + new CreatureToken(3, 5, "3/5 Soldier creature", SubType.SOLDIER), null, Duration.Custom + )); + this.withInterveningIf(SourceIsEnchantmentCondition.instance); + this.withRuleTextReplacement(true); + this.setTriggerPhrase("When you have 10 or less life, "); } private OpalAvengerStateTriggeredAbility(final OpalAvengerStateTriggeredAbility ability) { @@ -56,38 +61,11 @@ class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getState().getPlayer(getControllerId()) != null) { - return game.getState().getPlayer(getControllerId()).getLife() <= 10; - } - return false; - } - - @Override - public boolean checkInterveningIfClause(Game game) { - if (getSourcePermanentIfItStillExists(game) != null) { - return getSourcePermanentIfItStillExists(game).isEnchantment(game); - } - return false; - } - -} - -class OpalAvengerToken extends TokenImpl { - - public OpalAvengerToken() { - super("Soldier", "3/5 Soldier creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SOLDIER); - power = new MageInt(3); - toughness = new MageInt(5); - } - - private OpalAvengerToken(final OpalAvengerToken token) { - super(token); - } - - @Override - public OpalAvengerToken copy() { - return new OpalAvengerToken(this); + return Optional + .ofNullable(getControllerId()) + .map(game::getPlayer) + .map(Player::getLife) + .filter(x -> x <= 10) + .isPresent(); } } diff --git a/Mage.Sets/src/mage/cards/o/OpalCaryatid.java b/Mage.Sets/src/mage/cards/o/OpalCaryatid.java index 33b04a36c3c..b0b0c7ca819 100644 --- a/Mage.Sets/src/mage/cards/o/OpalCaryatid.java +++ b/Mage.Sets/src/mage/cards/o/OpalCaryatid.java @@ -1,9 +1,7 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,8 +9,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -21,19 +18,18 @@ import java.util.UUID; */ public final class OpalCaryatid extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalCaryatid(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); // When an opponent casts a creature spell, if Opal Caryatid is an enchantment, Opal Caryatid becomes a 2/2 Soldier creature. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalCaryatidSoldierToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 2, 2, "2/2 Soldier creature", SubType.SOLDIER + ), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalCaryatid(final OpalCaryatid card) { @@ -45,22 +41,3 @@ public final class OpalCaryatid extends CardImpl { return new OpalCaryatid(this); } } - -class OpalCaryatidSoldierToken extends TokenImpl { - - public OpalCaryatidSoldierToken() { - super("Soldier", "2/2 Soldier creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SOLDIER); - power = new MageInt(2); - toughness = new MageInt(2); - } - - private OpalCaryatidSoldierToken(final OpalCaryatidSoldierToken token) { - super(token); - } - - public OpalCaryatidSoldierToken copy() { - return new OpalCaryatidSoldierToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalChampion.java b/Mage.Sets/src/mage/cards/o/OpalChampion.java index f99bb73367e..24e8386ebf7 100644 --- a/Mage.Sets/src/mage/cards/o/OpalChampion.java +++ b/Mage.Sets/src/mage/cards/o/OpalChampion.java @@ -1,9 +1,7 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; @@ -12,8 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -22,19 +19,18 @@ import java.util.UUID; */ public final class OpalChampion extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalChampion(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // When an opponent casts a creature spell, if Opal Champion is an enchantment, Opal Champion becomes a 3/3 Knight creature with first strike. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalChampionKnight(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 3, 3, "3/3 Knight creature with first strike", SubType.KNIGHT + ).withAbility(FirstStrikeAbility.getInstance()), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalChampion(final OpalChampion card) { @@ -46,23 +42,3 @@ public final class OpalChampion extends CardImpl { return new OpalChampion(this); } } - -class OpalChampionKnight extends TokenImpl { - - public OpalChampionKnight() { - super("Knight", "3/3 Knight creature with first strike"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.KNIGHT); - power = new MageInt(3); - toughness = new MageInt(3); - this.addAbility(FirstStrikeAbility.getInstance()); - } - - private OpalChampionKnight(final OpalChampionKnight token) { - super(token); - } - - public OpalChampionKnight copy() { - return new OpalChampionKnight(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalGargoyle.java b/Mage.Sets/src/mage/cards/o/OpalGargoyle.java index 9757fd18216..db6dd091d7d 100644 --- a/Mage.Sets/src/mage/cards/o/OpalGargoyle.java +++ b/Mage.Sets/src/mage/cards/o/OpalGargoyle.java @@ -1,9 +1,7 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -12,8 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -22,19 +19,18 @@ import java.util.UUID; */ public final class OpalGargoyle extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalGargoyle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // When an opponent casts a creature spell, if Opal Gargoyle is an enchantment, Opal Gargoyle becomes a 2/2 Gargoyle creature with flying. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalGargoyleToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 2, 2, "2/2 Gargoyle creature with flying", SubType.GARGOYLE + ).withAbility(FlyingAbility.getInstance()), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalGargoyle(final OpalGargoyle card) { @@ -46,23 +42,3 @@ public final class OpalGargoyle extends CardImpl { return new OpalGargoyle(this); } } - -class OpalGargoyleToken extends TokenImpl { - - public OpalGargoyleToken() { - super("Gargoyle", "2/2 Gargoyle creature with flying"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.GARGOYLE); - power = new MageInt(2); - toughness = new MageInt(2); - this.addAbility(FlyingAbility.getInstance()); - } - - private OpalGargoyleToken(final OpalGargoyleToken token) { - super(token); - } - - public OpalGargoyleToken copy() { - return new OpalGargoyleToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalGuardian.java b/Mage.Sets/src/mage/cards/o/OpalGuardian.java index 976391c2799..8cf25a495c0 100644 --- a/Mage.Sets/src/mage/cards/o/OpalGuardian.java +++ b/Mage.Sets/src/mage/cards/o/OpalGuardian.java @@ -1,10 +1,8 @@ package mage.cards.o; -import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ProtectionAbility; @@ -14,8 +12,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -24,19 +21,19 @@ import java.util.UUID; */ public final class OpalGuardian extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalGuardian(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}{W}"); // When an opponent casts a creature spell, if Opal Guardian is an enchantment, Opal Guardian becomes a 3/4 Gargoyle creature with flying and protection from red. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new BecomesCreatureSourceEffect( - new OpalGuardianGargoyle(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A_CREATURE, false - ).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( + new CreatureToken( + 3, 4, "3/4 Gargoyle creature with " + + "flying and protection from red", SubType.GARGOYLE + ).withAbility(FlyingAbility.getInstance()).withAbility(ProtectionAbility.from(ObjectColor.RED)), + null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalGuardian(final OpalGuardian card) { @@ -48,23 +45,3 @@ public final class OpalGuardian extends CardImpl { return new OpalGuardian(this); } } - -class OpalGuardianGargoyle extends TokenImpl { - public OpalGuardianGargoyle() { - super("Gargoyle", "3/4 Gargoyle creature with flying and protection from red"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.GARGOYLE); - power = new MageInt(3); - toughness = new MageInt(4); - this.addAbility(FlyingAbility.getInstance()); - this.addAbility(ProtectionAbility.from(ObjectColor.RED)); - } - - private OpalGuardianGargoyle(final OpalGuardianGargoyle token) { - super(token); - } - - public OpalGuardianGargoyle copy() { - return new OpalGuardianGargoyle(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OpalTitan.java b/Mage.Sets/src/mage/cards/o/OpalTitan.java index 1a8d13d5b78..c8f00d4bd72 100644 --- a/Mage.Sets/src/mage/cards/o/OpalTitan.java +++ b/Mage.Sets/src/mage/cards/o/OpalTitan.java @@ -4,15 +4,13 @@ import mage.MageObjectReference; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; @@ -24,10 +22,6 @@ import java.util.UUID; */ public final class OpalTitan extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition( - new FilterEnchantmentPermanent("this permanent is an enchantment") - ); - public OpalTitan(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); @@ -35,7 +29,8 @@ public final class OpalTitan extends CardImpl { this.addAbility(new SpellCastOpponentTriggeredAbility( Zone.BATTLEFIELD, new OpalTitanBecomesCreatureEffect(), StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.SPELL - ).withInterveningIf(condition)); + ).withInterveningIf(SourceIsEnchantmentCondition.instance) + .setTriggerPhrase("When an opponent casts a creature spell, ")); } private OpalTitan(final OpalTitan card) { @@ -52,7 +47,7 @@ class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl { OpalTitanBecomesCreatureEffect() { super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); - staticText = "{this} becomes a 4/4 Giant creature with protection from each of that spell's colors."; + staticText = "it becomes a 4/4 Giant creature with protection from each of that spell's colors."; this.addDependencyType(DependencyType.BecomeCreature); } @@ -120,5 +115,4 @@ class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl { || layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; } - } diff --git a/Mage.Sets/src/mage/cards/v/VeilOfBirds.java b/Mage.Sets/src/mage/cards/v/VeilOfBirds.java index 602dcd2da30..374b13ce618 100644 --- a/Mage.Sets/src/mage/cards/v/VeilOfBirds.java +++ b/Mage.Sets/src/mage/cards/v/VeilOfBirds.java @@ -1,9 +1,7 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -12,8 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -22,15 +19,18 @@ import java.util.UUID; */ public final class VeilOfBirds extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition(new FilterEnchantmentPermanent("{this} is an enchantment")); - public VeilOfBirds(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); // When an opponent casts a spell, if Veil of Birds is an enchantment, Veil of Birds becomes a 1/1 Bird creature with flying. this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new VeilOfBirdsToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A, false).withInterveningIf(condition)); + new CreatureToken( + 1, 1, "1/1 Bird creature with flying", SubType.BIRD + ).withAbility(FlyingAbility.getInstance()), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a spell, ")); } private VeilOfBirds(final VeilOfBirds card) { @@ -42,23 +42,3 @@ public final class VeilOfBirds extends CardImpl { return new VeilOfBirds(this); } } - -class VeilOfBirdsToken extends TokenImpl { - - public VeilOfBirdsToken() { - super("Bird", "1/1 creature with flying"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.BIRD); - power = new MageInt(1); - toughness = new MageInt(1); - this.addAbility(FlyingAbility.getInstance()); - } - - private VeilOfBirdsToken(final VeilOfBirdsToken token) { - super(token); - } - - public VeilOfBirdsToken copy() { - return new VeilOfBirdsToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VeiledApparition.java b/Mage.Sets/src/mage/cards/v/VeiledApparition.java index b84dd01866e..0e00a764e22 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledApparition.java +++ b/Mage.Sets/src/mage/cards/v/VeiledApparition.java @@ -1,9 +1,7 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; @@ -15,8 +13,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -25,15 +22,21 @@ import java.util.UUID; */ public final class VeiledApparition extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition(new FilterEnchantmentPermanent("{this} is an enchantment")); - public VeiledApparition(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); // When an opponent casts a spell, if Veiled Apparition is an enchantment, Veiled Apparition becomes a 3/3 Illusion creature with flying and "At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}." this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new VeiledApparitionToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A, false).withInterveningIf(condition)); + new CreatureToken( + 3, 3, "3/3 Illusion creature with flying and \"At the beginning " + + "of your upkeep, sacrifice this creature unless you pay {1}{U}.\"", SubType.ILLUSION + ).withAbility(FlyingAbility.getInstance()).withAbility(new BeginningOfUpkeepTriggeredAbility( + new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl<>("{1}{U}")) + )), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a spell, ")); } private VeiledApparition(final VeiledApparition card) { @@ -45,26 +48,3 @@ public final class VeiledApparition extends CardImpl { return new VeiledApparition(this); } } - -class VeiledApparitionToken extends TokenImpl { - - VeiledApparitionToken() { - super("Illusion", "3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice {this} unless you pay {1}{U}."); - cardType.add(CardType.CREATURE); - subtype.add(SubType.ILLUSION); - power = new MageInt(3); - toughness = new MageInt(3); - this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl<>("{1}{U}")) - )); - } - - private VeiledApparitionToken(final VeiledApparitionToken token) { - super(token); - } - - public VeiledApparitionToken copy() { - return new VeiledApparitionToken(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java index 66092e37d46..b18d6fc37bc 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java +++ b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java @@ -1,7 +1,7 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.StateTriggeredAbility; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,9 +11,11 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import mage.players.Player; +import java.util.Objects; +import java.util.Set; import java.util.UUID; /** @@ -41,9 +43,14 @@ public final class VeiledCrocodile extends CardImpl { class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { public VeiledCrocodileStateTriggeredAbility() { - super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new VeilCrocodileToken(), null, Duration.Custom)); - this.withRuleTextReplacement(false); - setTriggerPhrase("When a player has no cards in hand, if {this} is an enchantment, "); + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect( + new CreatureToken( + 4, 4, "4/4 Crocodile creature", SubType.CROCODILE + ), null, Duration.Custom + )); + this.withInterveningIf(SourceIsEnchantmentCondition.instance); + this.withRuleTextReplacement(true); + this.setTriggerPhrase("When a player has no cards in hand, "); } private VeiledCrocodileStateTriggeredAbility(final VeiledCrocodileStateTriggeredAbility ability) { @@ -57,41 +64,13 @@ class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - for (UUID playerId : game.getState().getPlayersInRange(controllerId, game)) { - Player player = game.getPlayer(playerId); - if (player != null - && player.getHand().isEmpty()) { - return true; - } - } - return false; - } - - @Override - public boolean checkInterveningIfClause(Game game) { - if (getSourcePermanentIfItStillExists(game) != null) { - return getSourcePermanentIfItStillExists(game).isEnchantment(game); - } - return false; - } - -} - -class VeilCrocodileToken extends TokenImpl { - - public VeilCrocodileToken() { - super("Crocodile", "4/4 Crocodile creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.CROCODILE); - power = new MageInt(4); - toughness = new MageInt(4); - } - - private VeilCrocodileToken(final VeilCrocodileToken token) { - super(token); - } - - public VeilCrocodileToken copy() { - return new VeilCrocodileToken(this); + return game + .getState() + .getPlayersInRange(getControllerId(), game) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getHand) + .anyMatch(Set::isEmpty); } } diff --git a/Mage.Sets/src/mage/cards/v/VeiledSentry.java b/Mage.Sets/src/mage/cards/v/VeiledSentry.java index ea5d93b8105..8c6238d454a 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledSentry.java +++ b/Mage.Sets/src/mage/cards/v/VeiledSentry.java @@ -2,13 +2,11 @@ package mage.cards.v; import mage.abilities.Ability; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.common.FilterEnchantmentPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; @@ -20,13 +18,14 @@ import java.util.UUID; */ public final class VeiledSentry extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition(new FilterEnchantmentPermanent("{this} is an enchantment")); - public VeiledSentry(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); // When an opponent casts a spell, if Veiled Sentry is an enchantment, Veiled Sentry becomes an Illusion creature with power and toughness each equal to that spell's converted mana cost. - this.addAbility(new SpellCastOpponentTriggeredAbility(new VeiledSentryEffect(), false).withInterveningIf(condition)); + this.addAbility(new SpellCastOpponentTriggeredAbility(new VeiledSentryEffect(), false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a spell, ")); } private VeiledSentry(final VeiledSentry card) { @@ -45,7 +44,7 @@ class VeiledSentryEffect extends ContinuousEffectImpl { public VeiledSentryEffect() { super(Duration.Custom, Outcome.BecomeCreature); - staticText = "{this} becomes an Illusion creature with power and toughness equal to that spell's mana value"; + staticText = "{this} becomes an Illusion creature with power and toughness each equal to that spell's mana value"; this.dependencyTypes.add(DependencyType.BecomeCreature); } diff --git a/Mage.Sets/src/mage/cards/v/VeiledSerpent.java b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java index 0023c47a30a..4fbe5a44683 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledSerpent.java +++ b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java @@ -1,10 +1,8 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.condition.common.SourceIsEnchantmentCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; @@ -14,10 +12,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterEnchantmentPermanent; -import mage.filter.common.FilterLandPermanent; -import mage.game.permanent.token.TokenImpl; +import mage.game.permanent.token.custom.CreatureToken; import java.util.UUID; @@ -26,15 +23,22 @@ import java.util.UUID; */ public final class VeiledSerpent extends CardImpl { - private static final Condition condition = new SourceMatchesFilterCondition(new FilterEnchantmentPermanent("{this} is an enchantment")); + private static final FilterPermanent filter = new FilterPermanent(SubType.ISLAND, "an Island"); public VeiledSerpent(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); // When an opponent casts a spell, if Veiled Serpent is an enchantment, Veiled Serpent becomes a 4/4 Serpent creature that can't attack unless defending player controls an Island. this.addAbility(new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect( - new VeiledSerpentToken(), null, Duration.WhileOnBattlefield - ), StaticFilters.FILTER_SPELL_A, false).withInterveningIf(condition)); + new CreatureToken( + 4, 4, "4/4 Serpent creature with " + + "\"This creature can't attack unless defending player controls an Island.\"", + SubType.SERPENT + ).withAbility(new SimpleStaticAbility(new CantAttackUnlessDefenderControllsPermanent(filter))), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A, false) + .withInterveningIf(SourceIsEnchantmentCondition.instance) + .withRuleTextReplacement(true) + .setTriggerPhrase("When an opponent casts a spell, ")); // Cycling {2} this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); @@ -49,25 +53,3 @@ public final class VeiledSerpent extends CardImpl { return new VeiledSerpent(this); } } - -class VeiledSerpentToken extends TokenImpl { - - public VeiledSerpentToken() { - super("Serpent", "4/4 Serpent creature"); - cardType.add(CardType.CREATURE); - subtype.add(SubType.SERPENT); - power = new MageInt(4); - toughness = new MageInt(4); - this.addAbility(new SimpleStaticAbility( - new CantAttackUnlessDefenderControllsPermanent( - new FilterLandPermanent(SubType.ISLAND, "an Island")))); - } - - private VeiledSerpentToken(final VeiledSerpentToken token) { - super(token); - } - - public VeiledSerpentToken copy() { - return new VeiledSerpentToken(this); - } -} diff --git a/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java index bbd90879091..9f702612c74 100644 --- a/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java @@ -12,7 +12,11 @@ import mage.game.permanent.Permanent; */ public class OpponentPlaysLandTriggeredAbility extends TriggeredAbilityImpl { - public OpponentPlaysLandTriggeredAbility(Zone zone, Effect effect, Boolean optional) { + public OpponentPlaysLandTriggeredAbility(Effect effect, boolean optional) { + this(Zone.BATTLEFIELD, effect, optional); + } + + public OpponentPlaysLandTriggeredAbility(Zone zone, Effect effect, boolean optional) { super(zone, effect, optional); setTriggerPhrase("Whenever an opponent plays a land, "); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/SourceIsEnchantmentCondition.java b/Mage/src/main/java/mage/abilities/condition/common/SourceIsEnchantmentCondition.java new file mode 100644 index 00000000000..246308b6e59 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/SourceIsEnchantmentCondition.java @@ -0,0 +1,27 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; + +import java.util.Optional; + +/** + * @author TheElk801 + */ +public enum SourceIsEnchantmentCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return Optional + .ofNullable(source.getSourcePermanentOrLKI(game)) + .filter(permanent -> permanent.isEnchantment(game)) + .isPresent(); + } + + @Override + public String toString() { + return "this permanent is an enchantment"; + } +}