diff --git a/Mage.Sets/src/mage/cards/t/TezzeretBetrayerOfFlesh.java b/Mage.Sets/src/mage/cards/t/TezzeretBetrayerOfFlesh.java new file mode 100644 index 00000000000..26f01646fdd --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TezzeretBetrayerOfFlesh.java @@ -0,0 +1,197 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.command.emblems.TezzeretBetrayerOfFleshEmblem; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetArtifactPermanent; +import mage.util.CardUtil; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TezzeretBetrayerOfFlesh extends CardImpl { + + public TezzeretBetrayerOfFlesh(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.TEZZERET); + this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4)); + + // The first activated ability of an artifact you activate each turn costs {2} less to activate. + this.addAbility(new SimpleStaticAbility( + new TezzeretBetrayerOfFleshReductionEffect() + ), new TezzeretBetrayerOfFleshWatcher()); + + // +1: Draw two cards. Then discard two cards unless you discard an artifact card. + Ability ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(2), 1); + ability.addEffect(new DoIfCostPaid( + null, new DiscardControllerEffect(2), + new DiscardCardCost(StaticFilters.FILTER_CARD_ARTIFACT_AN) + .setText("discard an artifact card instead of discarding two cards") + ).setText("Then discard two cards unless you discard an artifact card")); + this.addAbility(ability); + + // −2: Target artifact becomes an artifact creature. If it isn't a Vehicle, it has base power and toughness 4/4. + ability = new LoyaltyAbility(new TezzeretBetrayerOfFleshTypeEffect(), -2); + ability.addTarget(new TargetArtifactPermanent()); + this.addAbility(ability); + + // −6: You get an emblem with "Whenever an artifact you control becomes tapped, draw a card." + this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new TezzeretBetrayerOfFleshEmblem()), -6)); + } + + private TezzeretBetrayerOfFlesh(final TezzeretBetrayerOfFlesh card) { + super(card); + } + + @Override + public TezzeretBetrayerOfFlesh copy() { + return new TezzeretBetrayerOfFlesh(this); + } +} + +class TezzeretBetrayerOfFleshReductionEffect extends CostModificationEffectImpl { + + TezzeretBetrayerOfFleshReductionEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "the first activated ability of an artifact you activate each turn costs {2} less to activate"; + } + + private TezzeretBetrayerOfFleshReductionEffect(final TezzeretBetrayerOfFleshReductionEffect effect) { + super(effect); + } + + @Override + public TezzeretBetrayerOfFleshReductionEffect copy() { + return new TezzeretBetrayerOfFleshReductionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + CardUtil.reduceCost(abilityToModify, 2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify.isControlledBy(source.getControllerId()) + && abilityToModify instanceof ActivatedAbility + && TezzeretBetrayerOfFleshWatcher.checkPlayer(game, abilityToModify); + } +} + +class TezzeretBetrayerOfFleshWatcher extends Watcher { + + private final Set playerSet = new HashSet<>(); + + TezzeretBetrayerOfFleshWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.ACTIVATED_ABILITY) { + return; + } + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent != null && permanent.isArtifact(game)) { + playerSet.add(event.getPlayerId()); + } + } + + @Override + public void reset() { + super.reset(); + playerSet.clear(); + } + + public static boolean checkPlayer(Game game, Ability ability) { + if (game.getState() + .getWatcher(TezzeretBetrayerOfFleshWatcher.class) + .playerSet + .contains(ability.getControllerId())) { + return false; + } + Permanent permanent = ability.getSourcePermanentOrLKI(game); + return permanent != null && permanent.isArtifact(game); + } +} + +class TezzeretBetrayerOfFleshTypeEffect extends ContinuousEffectImpl { + + TezzeretBetrayerOfFleshTypeEffect() { + super(Duration.Custom, Outcome.BecomeCreature); + staticText = "target artifact becomes an artifact creature. " + + "If it isn't a Vehicle, it has base power and toughness 4/4"; + } + + private TezzeretBetrayerOfFleshTypeEffect(final TezzeretBetrayerOfFleshTypeEffect effect) { + super(effect); + } + + @Override + public TezzeretBetrayerOfFleshTypeEffect copy() { + return new TezzeretBetrayerOfFleshTypeEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + discard(); + return false; + } + switch (layer) { + case TypeChangingEffects_4: + permanent.addCardType(game, CardType.ARTIFACT, CardType.CREATURE); + return true; + case PTChangingEffects_7: + if (sublayer != SubLayer.SetPT_7b + || permanent.hasSubtype(SubType.VEHICLE, game)) { + return false; + } + permanent.getPower().setValue(4); + permanent.getToughness().setValue(4); + return true; + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + switch (layer) { + case TypeChangingEffects_4: + case PTChangingEffects_7: + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java index 1289663ac4b..2e0fa86215b 100644 --- a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java +++ b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java @@ -271,6 +271,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Tatsunari, Toad Rider", 123, Rarity.RARE, mage.cards.t.TatsunariToadRider.class)); cards.add(new SetCardInfo("Teachings of the Kirin", 212, Rarity.RARE, mage.cards.t.TeachingsOfTheKirin.class)); cards.add(new SetCardInfo("Tempered in Solitude", 165, Rarity.UNCOMMON, mage.cards.t.TemperedInSolitude.class)); + cards.add(new SetCardInfo("Tezzeret, Betrayer of Flesh", 84, Rarity.MYTHIC, mage.cards.t.TezzeretBetrayerOfFlesh.class)); cards.add(new SetCardInfo("The Fall of Lord Konda", 12, Rarity.UNCOMMON, mage.cards.t.TheFallOfLordKonda.class)); cards.add(new SetCardInfo("The Kami War", 227, Rarity.MYTHIC, mage.cards.t.TheKamiWar.class)); cards.add(new SetCardInfo("The Long Reach of Night", 109, Rarity.UNCOMMON, mage.cards.t.TheLongReachOfNight.class)); diff --git a/Mage/src/main/java/mage/abilities/common/BecomesTappedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesTappedTriggeredAbility.java index 0d1ead46bd0..cefceedcb85 100644 --- a/Mage/src/main/java/mage/abilities/common/BecomesTappedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BecomesTappedTriggeredAbility.java @@ -1,20 +1,16 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** - * * @author jeffwadsworth */ public class BecomesTappedTriggeredAbility extends TriggeredAbilityImpl { @@ -23,7 +19,7 @@ public class BecomesTappedTriggeredAbility extends TriggeredAbilityImpl { protected boolean setTargetPointer; public BecomesTappedTriggeredAbility(Effect effect, boolean optional) { - this(effect, optional, new FilterPermanent("a permanent")); + this(effect, optional, StaticFilters.FILTER_PERMANENT_A); } public BecomesTappedTriggeredAbility(Effect effect, boolean optional, FilterPermanent filter) { @@ -31,7 +27,11 @@ public class BecomesTappedTriggeredAbility extends TriggeredAbilityImpl { } public BecomesTappedTriggeredAbility(Effect effect, boolean optional, FilterPermanent filter, boolean setTargetPointer) { - super(Zone.BATTLEFIELD, effect, optional); + this(Zone.BATTLEFIELD, effect, optional, filter, setTargetPointer); + } + + public BecomesTappedTriggeredAbility(Zone zone, Effect effect, boolean optional, FilterPermanent filter, boolean setTargetPointer) { + super(zone, effect, optional); this.filter = filter; this.setTargetPointer = setTargetPointer; } @@ -55,17 +55,17 @@ public class BecomesTappedTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - if (setTargetPointer) { - this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game)); - } - return true; + if (!filter.match(permanent, getSourceId(), getControllerId(), game)) { + return false; } - return false; + if (setTargetPointer) { + this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game)); + } + return true; } @Override public String getTriggerPhrase() { - return "Whenever " + filter.getMessage() + " becomes tapped, " ; + return "Whenever " + filter.getMessage() + " becomes tapped, "; } } diff --git a/Mage/src/main/java/mage/game/command/emblems/TezzeretBetrayerOfFleshEmblem.java b/Mage/src/main/java/mage/game/command/emblems/TezzeretBetrayerOfFleshEmblem.java new file mode 100644 index 00000000000..48a63cb23c9 --- /dev/null +++ b/Mage/src/main/java/mage/game/command/emblems/TezzeretBetrayerOfFleshEmblem.java @@ -0,0 +1,23 @@ +package mage.game.command.emblems; + +import mage.abilities.common.BecomesTappedTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.command.Emblem; + +/** + * @author TheElk801 + */ +public final class TezzeretBetrayerOfFleshEmblem extends Emblem { + + // −6: You get an emblem with "Whenever an artifact you control becomes tapped, draw a card." + public TezzeretBetrayerOfFleshEmblem() { + this.setName("Emblem Tezzeret"); + this.setExpansionSetCodeForImage("NEO"); + this.getAbilities().add(new BecomesTappedTriggeredAbility( + Zone.COMMAND, new DrawCardSourceControllerEffect(1), false, + StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT, false + )); + } +}