* Jandor's Ring - FIxed possible null pointer exception (discard has to be a cost still lacking).

This commit is contained in:
LevelX2 2017-07-23 20:55:57 +02:00
parent ee59ec80e2
commit f67cd391dd
2 changed files with 39 additions and 30 deletions

View file

@ -27,6 +27,8 @@
*/ */
package mage.cards.j; package mage.cards.j;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
@ -35,6 +37,7 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -59,7 +62,9 @@ public class JandorsRing extends CardImpl {
Watcher watcher = new JandorsRingWatcher(); Watcher watcher = new JandorsRingWatcher();
// {2}, {tap}, Discard the last card you drew this turn: Draw a card. // {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()); ability.addCost(new TapSourceCost());
this.addAbility(ability, watcher); this.addAbility(ability, watcher);
} }
@ -74,61 +79,60 @@ public class JandorsRing extends CardImpl {
} }
} }
class DiscardAndDrawEffect extends OneShotEffect { class JandorsRingEffect extends OneShotEffect {
public JandorsRingEffect() {
public DiscardAndDrawEffect() {
super(Outcome.Discard); super(Outcome.Discard);
staticText = "Draw a card";
} }
public DiscardAndDrawEffect(final DiscardAndDrawEffect effect) { public JandorsRingEffect(final JandorsRingEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public DiscardAndDrawEffect copy() { public JandorsRingEffect copy() {
return new DiscardAndDrawEffect(this); return new JandorsRingEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
JandorsRingWatcher watcher = (JandorsRingWatcher) game.getState().getWatchers().get(JandorsRingWatcher.class.getSimpleName()); JandorsRingWatcher watcher = (JandorsRingWatcher) game.getState().getWatchers().get(JandorsRingWatcher.class.getSimpleName());
if (watcher != null) {
FilterCard filter = new FilterCard(game.getCard(watcher.lastDrawnCard).getName()); UUID cardId = watcher.getLastDrewCard(source.getControllerId());
filter.add(new CardIdPredicate(watcher.lastDrawnCard)); Card card = game.getCard(cardId);
DiscardCardYouChooseTargetEffect effect = new DiscardCardYouChooseTargetEffect(filter, TargetController.YOU); if (card != null) {
FilterCard filter = new FilterCard(card.getName());
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 filter.add(new CardIdPredicate(card.getId()));
Player controller = game.getPlayer(source.getControllerId()); DiscardCardYouChooseTargetEffect effect = new DiscardCardYouChooseTargetEffect(filter, TargetController.YOU);
controller.drawCards(1, game); 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 true;
} }
return false; return false;
} }
} }
class JandorsRingWatcher extends Watcher { class JandorsRingWatcher extends Watcher {
UUID lastDrawnCard; Map<UUID, UUID> lastDrawnCards = new HashMap<>();
public JandorsRingWatcher() { public JandorsRingWatcher() {
super(JandorsRingWatcher.class.getSimpleName(), WatcherScope.PLAYER); super(JandorsRingWatcher.class.getSimpleName(), WatcherScope.GAME);
this.lastDrawnCard = null;
} }
public JandorsRingWatcher(final JandorsRingWatcher watcher) { public JandorsRingWatcher(final JandorsRingWatcher watcher) {
super(watcher); super(watcher);
this.lastDrawnCard = watcher.lastDrawnCard; this.lastDrawnCards.putAll(watcher.lastDrawnCards);
} }
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.DREW_CARD) { if (event.getType() == GameEvent.EventType.DREW_CARD) {
lastDrawnCard = event.getTargetId(); lastDrawnCards.putIfAbsent(event.getPlayerId(), event.getTargetId());
}
if (event.getType() == GameEvent.EventType.CLEANUP_STEP_POST) {
lastDrawnCard = null;
} }
} }
@ -140,7 +144,11 @@ class JandorsRingWatcher extends Watcher {
@Override @Override
public void reset() { public void reset() {
super.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) { public boolean apply(Game game, Ability source) {
JandorsRingWatcher watcher = (JandorsRingWatcher) game.getState().getWatchers().get(JandorsRingWatcher.class.getSimpleName()); 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 @Override
@ -160,5 +169,4 @@ enum WatchedCardInHandCondition implements Condition {
return "if last drawn card is still in hand"; return "if last drawn card is still in hand";
} }
} }

View file

@ -4,7 +4,6 @@ import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.constants.WatcherScope; import mage.constants.WatcherScope;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -43,7 +42,9 @@ public class CastFromHandWatcher extends Watcher {
step = game.getTurn().getStep(); step = game.getTurn().getStep();
} }
Spell spell = (Spell) game.getObject(event.getTargetId()); Spell spell = (Spell) game.getObject(event.getTargetId());
spellsCastFromHand.add(spell.getSourceId()); if (spell != null) {
spellsCastFromHand.add(spell.getSourceId());
}
} }
} }