From 8d4ec3f0edcf5360c33849457ab4698788bf7994 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 24 Sep 2013 16:40:11 +0200 Subject: [PATCH] Fixed Swere, Misdirection and Ricochet Trap to target only spells with exactly one target and allowing to replace it with exactly one different valid target. --- .../sets/mercadianmasques/Misdirection.java | 36 ++----------------- .../src/mage/sets/shardsofalara/Swerve.java | 4 +-- .../src/mage/sets/worldwake/RicochetTrap.java | 33 ++--------------- .../common/ChooseNewTargetsTargetEffect.java | 27 ++++++++++++-- .../mageobject/NumberOfTargetsPredicate.java | 13 ++++--- Mage/src/mage/game/stack/Spell.java | 32 +++++++++++++++-- 6 files changed, 70 insertions(+), 75 deletions(-) diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/Misdirection.java b/Mage.Sets/src/mage/sets/mercadianmasques/Misdirection.java index cbb43fa114..7d75051409 100644 --- a/Mage.Sets/src/mage/sets/mercadianmasques/Misdirection.java +++ b/Mage.Sets/src/mage/sets/mercadianmasques/Misdirection.java @@ -32,22 +32,18 @@ import java.util.UUID; import mage.constants.CardType; import mage.constants.Rarity; import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostImpl; import mage.abilities.costs.Cost; import mage.abilities.costs.CostsImpl; import mage.abilities.costs.common.ExileFromHandCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseNewTargetsTargetEffect; import mage.cards.CardImpl; -import mage.constants.Outcome; import mage.filter.FilterSpell; import mage.filter.common.FilterOwnedCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardIdPredicate; import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.mageobject.NumberOfTargetsPredicate; -import mage.game.Game; -import mage.game.stack.Spell; import mage.target.TargetSpell; import mage.target.common.TargetCardInHand; @@ -57,8 +53,7 @@ import mage.target.common.TargetCardInHand; */ public class Misdirection extends CardImpl { - private static final FilterSpell filter2 = new FilterSpell(); - + private static final FilterSpell filter2 = new FilterSpell("spell with a single target"); static { filter2.add(new NumberOfTargetsPredicate(1)); } @@ -78,7 +73,7 @@ public class Misdirection extends CardImpl { costs.add(new ExileFromHandCost(new TargetCardInHand(filterCardInHand))); this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl("You may exile a blue card from your hand rather than pay Misdirection's mana cost", costs)); // Change the target of target spell with a single target. - this.getSpellAbility().addEffect(new MisdirectionEffect()); + this.getSpellAbility().addEffect(new ChooseNewTargetsTargetEffect(true, true)); this.getSpellAbility().addTarget(new TargetSpell(filter2)); } @@ -92,28 +87,3 @@ public class Misdirection extends CardImpl { } } -class MisdirectionEffect extends OneShotEffect { - - public MisdirectionEffect() { - super(Outcome.Neutral); - staticText = "Change the target of target spell with a single target"; - } - - public MisdirectionEffect(final MisdirectionEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(source.getFirstTarget()); - if (spell != null && source.getControllerId() != null) { - return spell.chooseNewTargets(game, source.getControllerId()); - } - return false; - } - - @Override - public MisdirectionEffect copy() { - return new MisdirectionEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/shardsofalara/Swerve.java b/Mage.Sets/src/mage/sets/shardsofalara/Swerve.java index c3b4f2f5c4..1196542639 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/Swerve.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/Swerve.java @@ -42,7 +42,7 @@ import mage.target.TargetSpell; */ public class Swerve extends CardImpl { - private static final FilterSpell filter = new FilterSpell(); + private static final FilterSpell filter = new FilterSpell("spell with a single target"); static { filter.add(new NumberOfTargetsPredicate(1)); @@ -56,7 +56,7 @@ public class Swerve extends CardImpl { this.color.setBlue(true); // Change the target of target spell with a single target. - this.getSpellAbility().addEffect(new ChooseNewTargetsTargetEffect()); + this.getSpellAbility().addEffect(new ChooseNewTargetsTargetEffect(true, true)); this.getSpellAbility().addTarget(new TargetSpell(filter)); } diff --git a/Mage.Sets/src/mage/sets/worldwake/RicochetTrap.java b/Mage.Sets/src/mage/sets/worldwake/RicochetTrap.java index e253754b88..8e0582017f 100644 --- a/Mage.Sets/src/mage/sets/worldwake/RicochetTrap.java +++ b/Mage.Sets/src/mage/sets/worldwake/RicochetTrap.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Outcome; import mage.constants.WatcherScope; import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostImpl; import mage.abilities.costs.mana.ColoredManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseNewTargetsTargetEffect; import mage.cards.CardImpl; import mage.constants.ColoredManaSymbol; import mage.filter.FilterSpell; @@ -54,7 +53,7 @@ import mage.watchers.WatcherImpl; */ public class RicochetTrap extends CardImpl { - private static final FilterSpell filter = new FilterSpell(); + private static final FilterSpell filter = new FilterSpell("spell with a single target"); static { filter.add(new NumberOfTargetsPredicate(1)); @@ -71,7 +70,7 @@ public class RicochetTrap extends CardImpl { this.getSpellAbility().addAlternativeCost(new RicochetTrapAlternativeCost()); // Change the target of target spell with a single target. - this.getSpellAbility().addEffect(new RicochetTrapEffect()); + this.getSpellAbility().addEffect(new ChooseNewTargetsTargetEffect(true, true)); this.getSpellAbility().addTarget(new TargetSpell(filter)); this.addWatcher(new RicochetTrapWatcher()); @@ -154,29 +153,3 @@ class RicochetTrapAlternativeCost extends AlternativeCostImpl { - - public RicochetTrapEffect() { - super(Outcome.Neutral); - staticText = "Change the target of target spell with a single target"; - } - - public RicochetTrapEffect(final RicochetTrapEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(source.getFirstTarget()); - if (spell != null && source.getControllerId() != null) { - return spell.chooseNewTargets(game, source.getControllerId()); - } - return false; - } - - @Override - public RicochetTrapEffect copy() { - return new RicochetTrapEffect(this); - } -} \ No newline at end of file diff --git a/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java b/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java index 19bdf90987..2eabce7df0 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java @@ -41,19 +41,35 @@ import mage.game.stack.Spell; */ public class ChooseNewTargetsTargetEffect extends OneShotEffect { + private boolean forceChange; + private boolean onlyOneTarget; + public ChooseNewTargetsTargetEffect() { + this(false, false); + } + + /** + * + * @param forceChange - forces the user to choose another target (only targets with maxtargets = 1 supported) + */ + + public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget) { super(Outcome.Benefit); + this.forceChange = forceChange; + this.onlyOneTarget = onlyOneTarget; } public ChooseNewTargetsTargetEffect(final ChooseNewTargetsTargetEffect effect) { super(effect); + this.forceChange = effect.forceChange; + this.onlyOneTarget = effect.onlyOneTarget; } @Override public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(source.getFirstTarget()); if (spell != null) { - return spell.chooseNewTargets(game, source.getControllerId()); + return spell.chooseNewTargets(game, source.getControllerId(), forceChange, onlyOneTarget); } return false; } @@ -65,6 +81,13 @@ public class ChooseNewTargetsTargetEffect extends OneShotEffect { public boolean apply(MageObject input, Game game) { Spell spell = game.getStack().getSpell(input.getId()); if (spell != null) { - Targets target = spell.getSpellAbility().getTargets(); - if (target != null) { - if (target.size() == targets) { - return true; - } + Targets spellTargets = spell.getSpellAbility().getTargets(); + int numberOfTargets = 0; + for (Target target : spellTargets) { + numberOfTargets += target.getTargets().size(); + } + if (numberOfTargets == targets) { + return true; } } return false; diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 2e632e0855..2ed2e1908f 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -239,6 +239,19 @@ public class Spell> implements StackObject, Card { * @return */ public boolean chooseNewTargets(Game game, UUID playerId) { + return chooseNewTargets(game, playerId, false, false); + } + + /** + * + * + * @param game + * @param playerId + * @param forceChange - does only work for targets with maximal one targetId + * @param onlyOneTarget - 114.6b one target must be changed to another target + * @return + */ + public boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget) { Player player = game.getPlayer(playerId); if (player != null) { for(SpellAbility spellAbility: spellAbilities) { @@ -256,9 +269,22 @@ public class Spell> implements StackObject, Card { } else { name = object.getName(); } - if (name != null && player.chooseUse(spellAbility.getEffects().get(0).getOutcome(), "Change target from " + name + "?", game)) { - if (!player.chooseTarget(spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game)) { - newTarget.addTarget(targetId, spellAbility, game, false); + if (name != null && (forceChange || player.chooseUse(spellAbility.getEffects().get(0).getOutcome(), "Change target from " + name + "?", game))) { + if (forceChange && target.possibleTargets(this.getSourceId(), playerId, game).size() > 1 ) { + int iteration = 0; + do { + if (iteration > 0) { + game.informPlayer(player, "You may only select exactly one target that must be different from the origin target!"); + } + iteration++; + newTarget.clearChosen(); + player.chooseTarget(spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game); + } while (targetId.equals(newTarget.getFirstTarget()) || newTarget.getTargets().size() != 1); + + } else { + if (!player.chooseTarget(spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game)) { + newTarget.addTarget(targetId, spellAbility, game, false); + } } } else {