From fc4fb90115fdfb56cf3f6d6b2a4330d6e41788bb Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 15 Mar 2014 17:47:51 +0100 Subject: [PATCH] * Colossal Whale - Fixed a bug that the leaves battlefield event of Colossal Whale was triggered if the return from the exiled creature had a dies or leaves triggered ability on creatures. --- .../mage/sets/magic2014/ColossalWhale.java | 95 ++++++++++++------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/Mage.Sets/src/mage/sets/magic2014/ColossalWhale.java b/Mage.Sets/src/mage/sets/magic2014/ColossalWhale.java index 362b8e90512..f88aec63718 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ColossalWhale.java +++ b/Mage.Sets/src/mage/sets/magic2014/ColossalWhale.java @@ -40,7 +40,6 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; @@ -50,7 +49,6 @@ import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.WatcherImpl; /** * @@ -71,8 +69,9 @@ public class ColossalWhale extends CardImpl { this.addAbility(new IslandwalkAbility()); // Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield. this.addAbility(new ColossalWhaleAbility()); - this.addWatcher(new ColossalWhaleWatcher()); - + // Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature + // has a DiesTriggeredAll ability it triggers for the dying Banish Priest, what shouldn't happen) + this.addAbility(new ColossalWhaleReturnExiledAbility()); } @@ -143,52 +142,80 @@ class ColossalWhaleExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - // If Chained to the Rocks leaves the battlefield before its triggered ability resolves, + // If Whale leaves the battlefield before its triggered ability resolves, // the target creature won't be exiled. if (permanent != null) { - new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source); + return new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source); } return false; } } -class ColossalWhaleWatcher extends WatcherImpl { +/** + * Returns the exiled card as Banisher Priest leaves battlefield + * Uses no stack + * @author LevelX2 + */ - ColossalWhaleWatcher () { - super("BattlefieldLeft", WatcherScope.CARD); +class ColossalWhaleReturnExiledAbility extends TriggeredAbilityImpl { + + public ColossalWhaleReturnExiledAbility() { + super(Zone.BATTLEFIELD, new ReturnExiledCreatureColossalWhaleEffect()); + this.usesStack = false; + this.setRuleVisible(false); } - ColossalWhaleWatcher(final ColossalWhaleWatcher watcher) { - super(watcher); + public ColossalWhaleReturnExiledAbility(final ColossalWhaleReturnExiledAbility ability) { + super(ability); } @Override - public void watch(GameEvent event, Game game) { + public ColossalWhaleReturnExiledAbility copy() { + return new ColossalWhaleReturnExiledAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - ExileZone exile = game.getExile().getExileZone(this.getSourceId()); - Card sourceCard = game.getCard(this.getSourceId()); - if (exile != null && sourceCard != null) { - LinkedList cards = new LinkedList<>(exile); - for (UUID cardId: cards) { - Card card = game.getCard(cardId); - card.moveToZone(Zone.BATTLEFIELD, this.getSourceId(), game, false); - game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" was returned to battlefield from exile").toString()); - } - exile.clear(); - } + return true; } } - } - - @Override - public void reset() { - //don't reset condition each turn - only when this leaves the battlefield - } - - @Override - public ColossalWhaleWatcher copy() { - return new ColossalWhaleWatcher(this); + return false; + } +} + +class ReturnExiledCreatureColossalWhaleEffect extends OneShotEffect { + + public ReturnExiledCreatureColossalWhaleEffect() { + super(Outcome.Benefit); + this.staticText = "Return exiled creatures"; + } + + public ReturnExiledCreatureColossalWhaleEffect(final ReturnExiledCreatureColossalWhaleEffect effect) { + super(effect); + } + + @Override + public ReturnExiledCreatureColossalWhaleEffect copy() { + return new ReturnExiledCreatureColossalWhaleEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + ExileZone exile = game.getExile().getExileZone(source.getSourceId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (exile != null && sourceCard != null) { + LinkedList cards = new LinkedList<>(exile); + for (UUID cardId : cards) { + Card card = game.getCard(cardId); + card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); + game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString()); + } + exile.clear(); + return true; + } + return false; } }