From 114d726c81a0f102089fc6e1c8ff513e091b4480 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 25 Sep 2018 15:40:47 -0400 Subject: [PATCH] fixed Steel Hellkite destroying permanents controlled by players to whom it only dealt noncombat damage --- Mage.Sets/src/mage/cards/s/SteelHellkite.java | 88 +++++++++++++++---- 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SteelHellkite.java b/Mage.Sets/src/mage/cards/s/SteelHellkite.java index 504f6e7b6a..e08defa4f0 100644 --- a/Mage.Sets/src/mage/cards/s/SteelHellkite.java +++ b/Mage.Sets/src/mage/cards/s/SteelHellkite.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; @@ -9,19 +8,25 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; +import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; +import mage.game.events.DamageEvent; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.watchers.common.PlayerDamagedBySourceWatcher; +import mage.watchers.Watcher; + +import java.util.*; /** * @author nantuko @@ -37,9 +42,17 @@ public final class SteelHellkite extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // {2}: Steel Hellkite gets +1/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(2))); + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostSourceEffect(1, 0, Duration.EndOfTurn), + new GenericManaCost(2) + )); // {X}: Destroy each nonland permanent with converted mana cost X whose controller was dealt combat damage by Steel Hellkite this turn. Activate this ability only once each turn. - this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new SteelHellkiteDestroyEffect(), new ManaCostsImpl("{X}"))); + this.addAbility(new LimitedTimesPerTurnActivatedAbility( + Zone.BATTLEFIELD, + new SteelHellkiteDestroyEffect(), + new ManaCostsImpl("{X}") + ), new SteelHellkiteWatcher()); } @@ -71,15 +84,54 @@ class SteelHellkiteDestroyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int xValue = source.getManaCostsToPay().getX(); - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterNonlandPermanent(), source.getControllerId(), source.getSourceId(), game)) { - if (permanent.getConvertedManaCost() == xValue) { - PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get(PlayerDamagedBySourceWatcher.class.getSimpleName(), permanent.getControllerId()); - if (watcher != null && watcher.hasSourceDoneDamage(source.getSourceId(), game)) { - permanent.destroy(source.getSourceId(), game, false); - } - } + SteelHellkiteWatcher watcher = (SteelHellkiteWatcher) game.getState().getWatchers().get(SteelHellkiteWatcher.class.getSimpleName()); + if (watcher == null || watcher.getDamagedPlayers(source.getSourceId()).isEmpty()) { + return false; } - return true; + Set> predicateSet = new HashSet<>(); + for (UUID playerId : watcher.getDamagedPlayers(source.getSourceId())) { + predicateSet.add(new ControllerIdPredicate(playerId)); + } + FilterPermanent filter = new FilterNonlandPermanent(); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, source.getManaCostsToPay().getX())); + filter.add(Predicates.or(predicateSet)); + return new DestroyAllEffect(filter).apply(game, source); } } + +class SteelHellkiteWatcher extends Watcher { + + private final Map> damageMap = new HashMap<>(); + + public SteelHellkiteWatcher() { + super(SteelHellkiteWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public SteelHellkiteWatcher(final SteelHellkiteWatcher watcher) { + super(watcher); + this.damageMap.putAll(watcher.damageMap); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER && ((DamageEvent) event).isCombatDamage()) { + damageMap.putIfAbsent(event.getSourceId(), new HashSet<>()); + damageMap.get(event.getSourceId()).add(event.getTargetId()); + } + } + + @Override + public void reset() { + super.reset(); + this.damageMap.clear(); + } + + @Override + public Watcher copy() { + return new SteelHellkiteWatcher(this); + } + + public Set getDamagedPlayers(UUID damagerId) { + return damageMap.getOrDefault(damagerId, new HashSet<>()); + } +} \ No newline at end of file