diff --git a/Mage.Sets/src/mage/cards/h/HeatStroke.java b/Mage.Sets/src/mage/cards/h/HeatStroke.java index e2b04db1869..130b465e313 100644 --- a/Mage.Sets/src/mage/cards/h/HeatStroke.java +++ b/Mage.Sets/src/mage/cards/h/HeatStroke.java @@ -1,35 +1,46 @@ package mage.cards.h; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.UUID; + +import mage.MageObjectReference; +import mage.abilities.Ability; import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.BlockedPredicate; import mage.filter.predicate.permanent.BlockingPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.common.BlockedThisTurnWatcher; +import mage.watchers.common.WasBlockedThisTurnWatcher; /** * @author dustinroepsch */ public final class HeatStroke extends CardImpl { - private static final FilterPermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(Predicates.or(new BlockedPredicate(), new BlockingPredicate())); - } - public HeatStroke(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); // At end of combat, destroy each creature that blocked or was blocked this turn. - this.addAbility(new EndOfCombatTriggeredAbility(new DestroyAllEffect(filter) - .setText("destroy each creature that blocked or was blocked this turn"), false)); + Ability ability = new EndOfCombatTriggeredAbility(new HeatStrokeEffect(), false); + ability.addWatcher(new BlockedThisTurnWatcher()); + ability.addWatcher(new WasBlockedThisTurnWatcher()); + this.addAbility(ability); } public HeatStroke(final HeatStroke card) { @@ -41,3 +52,45 @@ public final class HeatStroke extends CardImpl { return new HeatStroke(this); } } + +class HeatStrokeEffect extends OneShotEffect { + + public HeatStrokeEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy each creature that blocked or was blocked this turn"; + } + + public HeatStrokeEffect(HeatStrokeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + BlockedThisTurnWatcher blockedWatcher = (BlockedThisTurnWatcher) game.getState().getWatchers().get(BlockedThisTurnWatcher.class.getSimpleName()); + WasBlockedThisTurnWatcher wasBlockedThisTurnWatcher = (WasBlockedThisTurnWatcher) game.getState().getWatchers().get(WasBlockedThisTurnWatcher.class.getSimpleName()); + Set inROI = new HashSet<>(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)); + boolean toRet = false; + Set toDestroy = new HashSet<>(); + + if (blockedWatcher != null){ + toDestroy.addAll(blockedWatcher.getBlockedThisTurnCreatures()); + } + if (wasBlockedThisTurnWatcher != null){ + toDestroy.addAll(wasBlockedThisTurnWatcher.getWasBlockedThisTurnCreatures()); + } + + for (MageObjectReference mor : toDestroy) { + Permanent permanent = mor.getPermanent(game); + if (permanent != null && permanent.isCreature() && inROI.contains(permanent)){ + permanent.destroy(source.getSourceId(), game, false); + toRet = true; + } + } + return toRet; + } + + @Override + public HeatStrokeEffect copy() { + return new HeatStrokeEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/j/JovensFerrets.java b/Mage.Sets/src/mage/cards/j/JovensFerrets.java new file mode 100644 index 00000000000..a4df82c443c --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JovensFerrets.java @@ -0,0 +1,111 @@ +package mage.cards.j; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.common.BlockedAttackerWatcher; + +/** + * + * @author noahg + */ +public final class JovensFerrets extends CardImpl { + + public JovensFerrets(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + + this.subtype.add(SubType.FERRET); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Joven's Ferrets attacks, it gets +0/+2 until end of turn. + Effect boostSourceEffect = new BoostSourceEffect(0, 2, Duration.EndOfTurn); + boostSourceEffect.setText("it gets +0/+2 until end of turn"); + this.addAbility(new AttacksTriggeredAbility(boostSourceEffect, false)); + + // At end of combat, tap all creatures that blocked Joven's Ferrets this turn. They don't untap during their controller's next untap step. + Ability eocAbility = new EndOfCombatTriggeredAbility(new JovensFerretsEffect(), false); + eocAbility.addWatcher(new BlockedAttackerWatcher()); + this.addAbility(eocAbility); + } + + public JovensFerrets(final JovensFerrets card) { + super(card); + } + + @Override + public JovensFerrets copy() { + return new JovensFerrets(this); + } +} + +class JovensFerretsEffect extends OneShotEffect { + + public JovensFerretsEffect() { + super(Outcome.Benefit); + } + + public JovensFerretsEffect(final JovensFerretsEffect effect) { + super(effect); + } + + @Override + public JovensFerretsEffect copy() { + return new JovensFerretsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && sourcePermanent != null) { + BlockedAttackerWatcher watcher = (BlockedAttackerWatcher) game.getState().getWatchers().get(BlockedAttackerWatcher.class.getSimpleName()); + if (watcher != null) { + List toTap = new ArrayList<>(); + for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) { + if (!creature.getId().equals(source.getSourceId())) { + if (watcher.creatureHasBlockedAttacker(sourcePermanent, creature, game)) { + toTap.add(creature); + } + } + } + for (Permanent creature : toTap) { + creature.tap(game); + DontUntapInControllersNextUntapStepTargetEffect effect = new DontUntapInControllersNextUntapStepTargetEffect(); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); + } + return true; + } + } + return false; + } + + @Override + public String getText(Mode mode) { + return "tap all creatures that blocked {this} this turn. They don't untap during their controller's next untap step."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index a9c872ebbc8..320442e8d5e 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -116,6 +116,7 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Ironclaw Curse", 76, Rarity.RARE, mage.cards.i.IronclawCurse.class)); cards.add(new SetCardInfo("Jinx", 29, Rarity.COMMON, mage.cards.j.Jinx.class)); cards.add(new SetCardInfo("Joven", 77, Rarity.COMMON, mage.cards.j.Joven.class)); + cards.add(new SetCardInfo("Joven's Ferrets", 89, Rarity.COMMON, mage.cards.j.JovensFerrets.class)); cards.add(new SetCardInfo("Joven's Tools", 108, Rarity.UNCOMMON, mage.cards.j.JovensTools.class)); cards.add(new SetCardInfo("Koskun Falls", 55, Rarity.RARE, mage.cards.k.KoskunFalls.class)); cards.add(new SetCardInfo("Koskun Keep", 114, Rarity.UNCOMMON, mage.cards.k.KoskunKeep.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index d466ec8914b..bee97c5b587 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -144,6 +144,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Jester's Mask", 211, Rarity.RARE, mage.cards.j.JestersMask.class)); cards.add(new SetCardInfo("Jeweled Amulet", 212, Rarity.UNCOMMON, mage.cards.j.JeweledAmulet.class)); cards.add(new SetCardInfo("Johtull Wurm", 168, Rarity.UNCOMMON, mage.cards.j.JohtullWurm.class)); + cards.add(new SetCardInfo("Joven's Ferrets", 169, Rarity.UNCOMMON, mage.cards.j.JovensFerrets.class)); cards.add(new SetCardInfo("Juniper Order Advocate", 20, Rarity.UNCOMMON, mage.cards.j.JuniperOrderAdvocate.class)); cards.add(new SetCardInfo("Karplusan Giant", 133, Rarity.UNCOMMON, mage.cards.k.KarplusanGiant.class)); cards.add(new SetCardInfo("Kaysa", 170, Rarity.RARE, mage.cards.k.Kaysa.class)); diff --git a/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java new file mode 100644 index 00000000000..65e44a07afc --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java @@ -0,0 +1,53 @@ + +package mage.watchers.common; + +import mage.MageObjectReference; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author noahg + */ +public class WasBlockedThisTurnWatcher extends Watcher { + + private final Set wasBlockedThisTurnCreatures; + + public WasBlockedThisTurnWatcher() { + super(WasBlockedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME); + wasBlockedThisTurnCreatures = new HashSet<>(); + } + + public WasBlockedThisTurnWatcher(final WasBlockedThisTurnWatcher watcher) { + super(watcher); + wasBlockedThisTurnCreatures = new HashSet<>(watcher.wasBlockedThisTurnCreatures); + } + + @Override + public Watcher copy() { + return new WasBlockedThisTurnWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + this.wasBlockedThisTurnCreatures.add(new MageObjectReference(event.getTargetId(), game)); + } + } + + public Set getWasBlockedThisTurnCreatures() { + return this.wasBlockedThisTurnCreatures; + } + + @Override + public void reset() { + super.reset(); + wasBlockedThisTurnCreatures.clear(); + } + +}