From f67cd391ddc020b4a70cc30571ba9915717ec4a7 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 23 Jul 2017 20:55:57 +0200 Subject: [PATCH] * Jandor's Ring - FIxed possible null pointer exception (discard has to be a cost still lacking). --- Mage.Sets/src/mage/cards/j/JandorsRing.java | 64 +++++++++++-------- .../watchers/common/CastFromHandWatcher.java | 5 +- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JandorsRing.java b/Mage.Sets/src/mage/cards/j/JandorsRing.java index 8b861e3d0ec..8a2d7581659 100644 --- a/Mage.Sets/src/mage/cards/j/JandorsRing.java +++ b/Mage.Sets/src/mage/cards/j/JandorsRing.java @@ -27,6 +27,8 @@ */ package mage.cards.j; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.Condition; @@ -35,6 +37,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -59,7 +62,9 @@ public class JandorsRing extends CardImpl { Watcher watcher = new JandorsRingWatcher(); // {2}, {tap}, Discard the last card you drew this turn: Draw a card. - Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new DiscardAndDrawEffect(), new ManaCostsImpl("{2}"), WatchedCardInHandCondition.instance, "Last drawn card still in hand?"); + // TODO: discard has to be a cost not a payment during resolution + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, + new JandorsRingEffect(), new ManaCostsImpl("{2}"), WatchedCardInHandCondition.instance, "Last drawn card still in hand?"); ability.addCost(new TapSourceCost()); this.addAbility(ability, watcher); } @@ -74,61 +79,60 @@ public class JandorsRing extends CardImpl { } } -class DiscardAndDrawEffect extends OneShotEffect { +class JandorsRingEffect extends OneShotEffect { - - public DiscardAndDrawEffect() { + public JandorsRingEffect() { super(Outcome.Discard); + staticText = "Draw a card"; } - public DiscardAndDrawEffect(final DiscardAndDrawEffect effect) { + public JandorsRingEffect(final JandorsRingEffect effect) { super(effect); } @Override - public DiscardAndDrawEffect copy() { - return new DiscardAndDrawEffect(this); + public JandorsRingEffect copy() { + return new JandorsRingEffect(this); } @Override public boolean apply(Game game, Ability source) { JandorsRingWatcher watcher = (JandorsRingWatcher) game.getState().getWatchers().get(JandorsRingWatcher.class.getSimpleName()); - - FilterCard filter = new FilterCard(game.getCard(watcher.lastDrawnCard).getName()); - filter.add(new CardIdPredicate(watcher.lastDrawnCard)); - DiscardCardYouChooseTargetEffect effect = new DiscardCardYouChooseTargetEffect(filter, TargetController.YOU); - - if (effect.apply(game, source)) {//Conditional was already checked, card should be in hand, but if for some weird reason it fails, the card won't be drawn, although the cost will already be paid - Player controller = game.getPlayer(source.getControllerId()); - controller.drawCards(1, game); + if (watcher != null) { + UUID cardId = watcher.getLastDrewCard(source.getControllerId()); + Card card = game.getCard(cardId); + if (card != null) { + FilterCard filter = new FilterCard(card.getName()); + filter.add(new CardIdPredicate(card.getId())); + DiscardCardYouChooseTargetEffect effect = new DiscardCardYouChooseTargetEffect(filter, TargetController.YOU); + if (effect.apply(game, source)) {//Conditional was already checked, card should be in hand, but if for some weird reason it fails, the card won't be drawn, although the cost will already be paid + Player controller = game.getPlayer(source.getControllerId()); + controller.drawCards(1, game); + } + } return true; } return false; } } - class JandorsRingWatcher extends Watcher { - UUID lastDrawnCard; + Map lastDrawnCards = new HashMap<>(); public JandorsRingWatcher() { - super(JandorsRingWatcher.class.getSimpleName(), WatcherScope.PLAYER); - this.lastDrawnCard = null; + super(JandorsRingWatcher.class.getSimpleName(), WatcherScope.GAME); } public JandorsRingWatcher(final JandorsRingWatcher watcher) { super(watcher); - this.lastDrawnCard = watcher.lastDrawnCard; + this.lastDrawnCards.putAll(watcher.lastDrawnCards); } @Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.DREW_CARD) { - lastDrawnCard = event.getTargetId(); - } - if (event.getType() == GameEvent.EventType.CLEANUP_STEP_POST) { - lastDrawnCard = null; + lastDrawnCards.putIfAbsent(event.getPlayerId(), event.getTargetId()); } } @@ -140,7 +144,11 @@ class JandorsRingWatcher extends Watcher { @Override public void reset() { super.reset(); - lastDrawnCard = null; + lastDrawnCards.clear(); + } + + public UUID getLastDrewCard(UUID playerId) { + return lastDrawnCards.getOrDefault(null, playerId); } } @@ -152,7 +160,8 @@ enum WatchedCardInHandCondition implements Condition { public boolean apply(Game game, Ability source) { JandorsRingWatcher watcher = (JandorsRingWatcher) game.getState().getWatchers().get(JandorsRingWatcher.class.getSimpleName()); - return watcher.lastDrawnCard != null && game.getPlayer(source.getControllerId()).getHand().contains(watcher.lastDrawnCard); + return watcher != null + && watcher.lastDrawnCards != null && game.getPlayer(source.getControllerId()).getHand().contains(watcher.getLastDrewCard(source.getControllerId())); } @Override @@ -160,5 +169,4 @@ enum WatchedCardInHandCondition implements Condition { return "if last drawn card is still in hand"; } - -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/watchers/common/CastFromHandWatcher.java b/Mage/src/main/java/mage/watchers/common/CastFromHandWatcher.java index 7d79471dc1c..6531c80dd44 100644 --- a/Mage/src/main/java/mage/watchers/common/CastFromHandWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/CastFromHandWatcher.java @@ -4,7 +4,6 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; import java.util.UUID; - import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; @@ -43,7 +42,9 @@ public class CastFromHandWatcher extends Watcher { step = game.getTurn().getStep(); } Spell spell = (Spell) game.getObject(event.getTargetId()); - spellsCastFromHand.add(spell.getSourceId()); + if (spell != null) { + spellsCastFromHand.add(spell.getSourceId()); + } } }