From d3bfeccb0133ac8ee8d626a79a57c9cafb3f4257 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 13 Nov 2018 18:29:12 -0600 Subject: [PATCH] - Added Veiled Sentry, Hidden Predators, Veiled Crocodile, Veiled Serpent. --- .../src/mage/cards/h/HiddenPredators.java | 131 ++++++++++++++++++ .../src/mage/cards/v/VeiledCrocodile.java | 127 +++++++++++++++++ Mage.Sets/src/mage/cards/v/VeiledSentry.java | 114 +++++++++++++++ Mage.Sets/src/mage/cards/v/VeiledSerpent.java | 75 ++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 4 + 5 files changed, 451 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HiddenPredators.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledCrocodile.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledSentry.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledSerpent.java diff --git a/Mage.Sets/src/mage/cards/h/HiddenPredators.java b/Mage.Sets/src/mage/cards/h/HiddenPredators.java new file mode 100644 index 0000000000..f5ff50d09b --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HiddenPredators.java @@ -0,0 +1,131 @@ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class HiddenPredators extends CardImpl { + + public HiddenPredators(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + + // When an opponent controls a creature with power 4 or greater, if Hidden Predators is an enchantment, Hidden Predators becomes a 4/4 Beast creature. + this.addAbility(new HiddenPredatorsStateTriggeredAbility()); + } + + public HiddenPredators(final HiddenPredators card) { + super(card); + } + + @Override + public HiddenPredators copy() { + return new HiddenPredators(this); + } +} + +class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + public HiddenPredatorsStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new HiddenPredatorsToken(), "", Duration.Custom, true, false)); + } + + public HiddenPredatorsStateTriggeredAbility(final HiddenPredatorsStateTriggeredAbility ability) { + super(ability); + } + + @Override + public HiddenPredatorsStateTriggeredAbility copy() { + return new HiddenPredatorsStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return !game.getBattlefield().getAllActivePermanents(filter, game).isEmpty(); + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When an opponent controls a creature with 4 or greater power, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +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); + } + + public HiddenPredatorsToken(final HiddenPredatorsToken token) { + super(token); + } + + public HiddenPredatorsToken copy() { + return new HiddenPredatorsToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java new file mode 100644 index 0000000000..c3790e5c73 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java @@ -0,0 +1,127 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +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.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledCrocodile extends CardImpl { + + public VeiledCrocodile(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // When a player has no cards in hand, if Veiled Crocodile is an enchantment, Veiled Crocodile becomes a 4/4 Crocodile creature. + this.addAbility(new VeiledCrocodileStateTriggeredAbility()); + } + + public VeiledCrocodile(final VeiledCrocodile card) { + super(card); + } + + @Override + public VeiledCrocodile copy() { + return new VeiledCrocodile(this); + } +} + +class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { + + public VeiledCrocodileStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new VeilCrocodileToken(), "", Duration.Custom, true, false)); + } + + public VeiledCrocodileStateTriggeredAbility(final VeiledCrocodileStateTriggeredAbility ability) { + super(ability); + } + + @Override + public VeiledCrocodileStateTriggeredAbility copy() { + return new VeiledCrocodileStateTriggeredAbility(this); + } + + @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) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When a player has no cards in hand, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +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); + } + + public VeilCrocodileToken(final VeilCrocodileToken token) { + super(token); + } + + public VeilCrocodileToken copy() { + return new VeilCrocodileToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledSentry.java b/Mage.Sets/src/mage/cards/v/VeiledSentry.java new file mode 100644 index 0000000000..8c79053975 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledSentry.java @@ -0,0 +1,114 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import static mage.constants.Layer.PTChangingEffects_7; +import static mage.constants.Layer.TypeChangingEffects_4; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledSentry extends CardImpl { + + 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. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new VeiledSentryEffect(), new FilterSpell(), false, SetTargetPointer.SPELL); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a spell, if Veiled Sentry is an enchantment, Veil Sentry becomes an Illusion creature with power and toughness equal to that spell's converted mana cost.")); + + } + + public VeiledSentry(final VeiledSentry card) { + super(card); + } + + @Override + public VeiledSentry copy() { + return new VeiledSentry(this); + } +} + +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 converted mana cost"; + } + + public VeiledSentryEffect(final VeiledSentryEffect effect) { + super(effect); + } + + @Override + public VeiledSentryEffect copy() { + return new VeiledSentryEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent veiledSentry = game.getPermanent(source.getSourceId()); + Spell spellCast = game.getSpell(targetPointer.getFirst(game, source)); + if (spellCast != null) { + game.getState().setValue(source + "cmcSpell", spellCast.getConvertedManaCost()); + } + if (veiledSentry == null) { + return false; + } + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + if (!veiledSentry.isCreature()) { + veiledSentry.addCardType(CardType.CREATURE); + } + if (!veiledSentry.getSubtype(game).contains(SubType.ILLUSION)) { + veiledSentry.getSubtype(game).add(SubType.ILLUSION); + } + } + break; + + case PTChangingEffects_7: + if (game.getState().getValue(source + "cmcSpell") != null) { + int cmc = (int) game.getState().getValue(source + "cmcSpell"); + if (sublayer == SubLayer.SetPT_7b) { + veiledSentry.addPower(cmc); + veiledSentry.addToughness(cmc); + } + } + } + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.PTChangingEffects_7 + || layer == Layer.TypeChangingEffects_4; + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledSerpent.java b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java new file mode 100644 index 0000000000..216133ebfd --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java @@ -0,0 +1,75 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledSerpent extends CardImpl { + + 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. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeiledSerpentToken(), "", Duration.WhileOnBattlefield, true, false), + new FilterSpell(), false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever 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.")); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public VeiledSerpent(final VeiledSerpent card) { + super(card); + } + + @Override + public VeiledSerpent copy() { + 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(Zone.BATTLEFIELD, + new CantAttackUnlessDefenderControllsPermanent( + new FilterLandPermanent(SubType.ISLAND, "an Island")))); + } + + public VeiledSerpentToken(final VeiledSerpentToken token) { + super(token); + } + + public VeiledSerpentToken copy() { + return new VeiledSerpentToken(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 5d3633fe30..64db33f2e2 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -164,6 +164,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Hidden Ancients", 260, Rarity.UNCOMMON, mage.cards.h.HiddenAncients.class)); cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); + cards.add(new SetCardInfo("Hidden Predators", 263, Rarity.RARE, mage.cards.h.HiddenPredators.class)); cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); cards.add(new SetCardInfo("Hidden Stag", 265, Rarity.RARE, mage.cards.h.HiddenStag.class)); cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); @@ -337,6 +338,9 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); cards.add(new SetCardInfo("Veil of Birds", 106, Rarity.COMMON, mage.cards.v.VeilOfBirds.class)); cards.add(new SetCardInfo("Veiled Apparition", 107, Rarity.UNCOMMON, mage.cards.v.VeiledApparition.class)); + cards.add(new SetCardInfo("Veiled Crocodile", 108, Rarity.RARE, mage.cards.v.VeiledCrocodile.class)); + cards.add(new SetCardInfo("Veiled Sentry", 109, Rarity.UNCOMMON, mage.cards.v.VeiledSentry.class)); + cards.add(new SetCardInfo("Veiled Serpent", 110, Rarity.COMMON, mage.cards.v.VeiledSerpent.class)); cards.add(new SetCardInfo("Venomous Fangs", 280, Rarity.COMMON, mage.cards.v.VenomousFangs.class)); cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class));