From c9bb0be016d1b13611d3ab25b34974bd669b6c78 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 24 Sep 2016 01:12:01 +0200 Subject: [PATCH] Reworked selected modes handling. That fixed the Subtle Strike targeting problem. --- Mage.Common/src/mage/view/CardView.java | 23 ++++---- .../src/mage/view/StackAbilityView.java | 6 ++- .../java/mage/player/ai/ComputerPlayer.java | 3 +- .../src/mage/player/human/HumanPlayer.java | 3 +- .../battleforzendikar/ZadaHedronGrinder.java | 9 ++-- .../mage/sets/chronicles/GoblinArtisans.java | 54 +++++++++---------- .../sets/dragonsoftarkir/IcefallRegent.java | 3 +- .../sets/fatereforged/MonasterySiege.java | 3 +- .../sets/kaladesh/CapturedByTheConsulate.java | 3 +- .../sets/magicorigins/PsychicRebuttal.java | 3 +- .../sets/planechase2012/ElderwoodScion.java | 3 +- .../src/mage/sets/scourge/GripOfChaos.java | 7 +-- .../shadowsoverinnistrad/AccursedWitch.java | 3 +- .../shadowsoverinnistrad/InfectiousCurse.java | 3 +- .../sets/shardsofalara/HinderingLight.java | 3 +- .../src/mage/sets/venservskoth/Torchling.java | 6 +-- .../sets/vintagemasters/KaerveksTorch.java | 3 +- .../test/AI/basic/CastDestroySpellsTest.java | 6 +-- .../mage/test/cards/modal/OneOrBothTest.java | 4 +- .../cards/single/bfz/BrutalExpulsionTest.java | 24 +++++---- .../java/org/mage/test/player/TestPlayer.java | 3 +- .../main/java/mage/abilities/AbilityImpl.java | 6 ++- Mage/src/main/java/mage/abilities/Modes.java | 37 +++++-------- ...getOfTargetSpellAbilityToSourceEffect.java | 11 ++-- .../mage/abilities/keyword/HeroicAbility.java | 5 +- .../mageobject/NumberOfTargetsPredicate.java | 4 +- .../other/TargetsPermanentPredicate.java | 3 +- Mage/src/main/java/mage/game/GameState.java | 12 +++-- Mage/src/main/java/mage/game/stack/Spell.java | 9 ++-- .../java/mage/game/stack/StackObjImpl.java | 7 ++- .../main/java/mage/players/PlayerImpl.java | 2 +- .../common/TargetCreatureOrPlaneswalker.java | 19 ++++++- .../main/java/mage/util/TargetAddress.java | 4 +- 33 files changed, 163 insertions(+), 131 deletions(-) diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 2e0414ecb8c..9accefe8ed5 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -30,7 +30,6 @@ package mage.view; import java.util.ArrayList; import java.util.List; import java.util.UUID; - import mage.MageObject; import mage.ObjectColor; import mage.abilities.Mode; @@ -55,7 +54,6 @@ import mage.game.stack.Spell; import mage.game.stack.StackAbility; import mage.target.Target; import mage.target.Targets; -import org.apache.log4j.Logger; /** * @author BetaSteward_at_googlemail.com @@ -81,7 +79,7 @@ public class CardView extends SimpleCardView { protected List manaCost; protected int convertedManaCost; protected Rarity rarity; - + protected MageObjectType mageObjectType = MageObjectType.NULL; protected boolean isAbility; @@ -323,7 +321,8 @@ public class CardView extends SimpleCardView { this.mageObjectType = MageObjectType.SPELL; Spell spell = (Spell) card; for (SpellAbility spellAbility : spell.getSpellAbilities()) { - for (Mode mode : spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { + Mode mode = spellAbility.getModes().get(modeId); if (mode.getTargets().size() > 0) { setTargets(spellAbility.getTargets()); } @@ -331,18 +330,19 @@ public class CardView extends SimpleCardView { } // show for modal spell, which mode was choosen if (spell.getSpellAbility().isModal()) { - for (Mode mode : spell.getSpellAbility().getModes().getSelectedModes()) { + for (UUID modeId : spell.getSpellAbility().getModes().getSelectedModes()) { + Mode mode = spell.getSpellAbility().getModes().get(modeId); this.rules.add("Chosen mode: " + mode.getEffects().getText(mode) + ""); } } } - + // Frame color this.frameColor = card.getFrameColor(game); // Frame style this.frameStyle = card.getFrameStyle(); - + // Get starting loyalty this.startingLoyalty = "" + card.getStartingLoyalty(); } @@ -355,7 +355,7 @@ public class CardView extends SimpleCardView { this.mageObjectType = MageObjectType.PERMANENT; this.power = Integer.toString(object.getPower().getValue()); this.toughness = Integer.toString(object.getToughness().getValue()); - this.loyalty = Integer.toString(((Permanent) object).getCounters((Game)null).getCount(CounterType.LOYALTY)); + this.loyalty = Integer.toString(((Permanent) object).getCounters((Game) null).getCount(CounterType.LOYALTY)); } else { this.power = object.getPower().toString(); this.toughness = object.getToughness().toString(); @@ -488,7 +488,7 @@ public class CardView extends SimpleCardView { this.rarity = Rarity.NA; this.type = token.getTokenType(); this.tokenDescriptor = token.getTokenDescriptor(); - this.tokenSetCode = token.getOriginalExpansionSetCode(); + this.tokenSetCode = token.getOriginalExpansionSetCode(); } protected final void setTargets(Targets targets) { @@ -547,7 +547,7 @@ public class CardView extends SimpleCardView { public String getLoyalty() { return loyalty; } - + public String getStartingLoyalty() { return startingLoyalty; } @@ -567,7 +567,7 @@ public class CardView extends SimpleCardView { public ObjectColor getColor() { return color; } - + public ObjectColor getFrameColor() { return frameColor; } @@ -807,4 +807,3 @@ public class CardView extends SimpleCardView { } } - diff --git a/Mage.Common/src/mage/view/StackAbilityView.java b/Mage.Common/src/mage/view/StackAbilityView.java index 9b195d1b5bb..1c5c6914d52 100644 --- a/Mage.Common/src/mage/view/StackAbilityView.java +++ b/Mage.Common/src/mage/view/StackAbilityView.java @@ -99,7 +99,8 @@ public class StackAbilityView extends CardView { private void updateTargets(Game game, StackAbility ability) { List names = new ArrayList<>(); - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); if (mode.getTargets().size() > 0) { setTargets(mode.getTargets()); } else { @@ -132,7 +133,8 @@ public class StackAbilityView extends CardView { // show for modal ability, which mode was choosen if (ability.isModal()) { Modes modes = ability.getModes(); - for (Mode mode : modes.getSelectedModes()) { + for (UUID modeId : modes.getSelectedModes()) { + Mode mode = modes.get(modeId); this.rules.add("Chosen mode: " + mode.getEffects().getText(mode) + ""); } } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 0d1a60d29dd..8f2d515fe35 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -1516,7 +1516,8 @@ public class ComputerPlayer extends PlayerImpl implements Player { //TODO: improve this; AvailableMode: for (Mode mode : modes.getAvailableModes(source, game)) { - for (Mode selectedMode : modes.getSelectedModes()) { + for (UUID selectedModeId : modes.getSelectedModes()) { + Mode selectedMode = modes.get(selectedModeId); if (selectedMode.getId().equals(mode.getId())) { continue AvailableMode; } diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 4b8bb57eece..03ca681e47f 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -1326,7 +1326,8 @@ public class HumanPlayer extends PlayerImpl { AvailableModes: for (Mode mode : modes.getAvailableModes(source, game)) { int timesSelected = 0; - for (Mode selectedMode : modes.getSelectedModes()) { + for (UUID selectedModeId : modes.getSelectedModes()) { + Mode selectedMode = modes.get(selectedModeId); if (mode.getId().equals(selectedMode.getId())) { if (modes.isEachModeMoreThanOnce()) { timesSelected++; diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java index 129686fc335..557f05bd6f1 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java @@ -104,7 +104,8 @@ class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl { if (isControlledInstantOrSorcery(spell)) { boolean targetsSource = false; for (Ability ability : spell.getSpellAbilities()) { - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); for (Target target : mode.getTargets()) { if (!target.isNotTarget()) { for (UUID targetId : target.getTargets()) { @@ -167,7 +168,8 @@ class ZadaHedronGrinderEffect extends OneShotEffect { Target usedTarget = null; setUsedTarget: for (Ability ability : spell.getSpellAbilities()) { - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); for (Target target : mode.getTargets()) { if (!target.isNotTarget() && target.getFirstTarget().equals(source.getSourceId())) { usedTarget = target.copy(); @@ -185,7 +187,8 @@ class ZadaHedronGrinderEffect extends OneShotEffect { Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); setTarget: - for (Mode mode : copy.getSpellAbility().getModes().getSelectedModes()) { + for (UUID modeId : copy.getSpellAbility().getModes().getSelectedModes()) { + Mode mode = copy.getSpellAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { if (target.getClass().equals(usedTarget.getClass())) { target.clearChosen(); // For targets with Max > 1 we need to clear before the text is comapred diff --git a/Mage.Sets/src/mage/sets/chronicles/GoblinArtisans.java b/Mage.Sets/src/mage/sets/chronicles/GoblinArtisans.java index a255033f825..271326e7b58 100644 --- a/Mage.Sets/src/mage/sets/chronicles/GoblinArtisans.java +++ b/Mage.Sets/src/mage/sets/chronicles/GoblinArtisans.java @@ -70,7 +70,7 @@ public class GoblinArtisans extends CardImpl { // {tap}: Flip a coin. If you win the flip, draw a card. If you lose the flip, counter target artifact spell you control that isn't the target of an ability from another creature named Goblin Artisans. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinArtisansEffect(), new TapSourceCost())); - + } public GoblinArtisans(final GoblinArtisans card) { @@ -83,15 +83,14 @@ public class GoblinArtisans extends CardImpl { } } - class GoblinArtisansEffect extends OneShotEffect { private static final FilterPermanent filter = new FilterPermanent("permanent named Goblin Artisans"); - + static { filter.add(new NamePredicate("Goblin Artisans")); } - + public GoblinArtisansEffect() { super(Outcome.Damage); staticText = "Flip a coin. If you win the flip, draw a card. If you lose the flip, counter target artifact spell you control that isn't the target of an ability from another creature named Goblin Artisans."; @@ -109,37 +108,38 @@ class GoblinArtisansEffect extends OneShotEffect { controller.drawCards(1, game); } else { List artifacts = game.getBattlefield().getActivePermanents(new FilterControlledArtifactPermanent(), source.getControllerId(), game); - if (artifacts.isEmpty()){//Don't even bother if there is no artifact to 'counter'/sacrifice + if (artifacts.isEmpty()) {//Don't even bother if there is no artifact to 'counter'/sacrifice return true; - } - + } + filter.add(Predicates.not(new PermanentIdPredicate(source.getSourceId()))); - //removed the activating instance of Artisans, btw, wasn't that filter declared as static final? How come I can do this here? :) - List list = game.getBattlefield().getAllActivePermanents(filter, game); - for (Permanent perm : list){ // should I limit below for a particular kind of ability? Going for the most general, it's unlikely there'll be any other artisans anyway, so not concerned about efficiency :p - for (Ability abil : perm.getAbilities(game)){//below is copied from TargetsPermanentPredicate, but why only "selectedModes"? Shouldnt be more general as well? - for (Mode mode : abil.getModes().getSelectedModes()){ + //removed the activating instance of Artisans, btw, wasn't that filter declared as static final? How come I can do this here? :) + List list = game.getBattlefield().getAllActivePermanents(filter, game); + for (Permanent perm : list) { // should I limit below for a particular kind of ability? Going for the most general, it's unlikely there'll be any other artisans anyway, so not concerned about efficiency :p + for (Ability abil : perm.getAbilities(game)) {//below is copied from TargetsPermanentPredicate, but why only "selectedModes"? Shouldnt be more general as well? + for (UUID modeId : abil.getModes().getSelectedModes()) { + Mode mode = abil.getModes().get(modeId); for (Target target : mode.getTargets()) { - for (UUID targetId : target.getTargets()) { - artifacts.remove(game.getPermanentOrLKIBattlefield(targetId)); - }// we could - }// remove this - }//closing bracers - }// pyramid, if it's bothering anyone - } //they are all one-liners after all :) - if (!artifacts.isEmpty()){ - Cards cards=new CardsImpl(); - for (Permanent perm : artifacts){ + for (UUID targetId : target.getTargets()) { + artifacts.remove(game.getPermanentOrLKIBattlefield(targetId)); + }// we could + }// remove this + }//closing bracers + }// pyramid, if it's bothering anyone + } //they are all one-liners after all :) + if (!artifacts.isEmpty()) { + Cards cards = new CardsImpl(); + for (Permanent perm : artifacts) { cards.add(perm.getId()); } - TargetCard target = new TargetCard(Zone.BATTLEFIELD, new FilterCard()); + TargetCard target = new TargetCard(Zone.BATTLEFIELD, new FilterCard()); controller.choose(Outcome.Sacrifice, cards, target, game); - game.getPermanent(target.getFirstTarget()).sacrifice(source.getSourceId(), game); - } + game.getPermanent(target.getFirstTarget()).sacrifice(source.getSourceId(), game); + } return true; - } } - + } + return false; } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java index 7a5b1418363..dfac065c16f 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java @@ -227,7 +227,8 @@ class IcefallRegentCostIncreaseEffect extends CostModificationEffectImpl { public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { - for (Mode mode : abilityToModify.getModes().getSelectedModes()) { + for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { + Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetUUID : target.getTargets()) { if (targetUUID.equals(source.getSourceId())) { diff --git a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java index 77e9e768e4c..d3b6e04e238 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java @@ -109,7 +109,8 @@ class MonasterySiegeCostIncreaseEffect extends CostModificationEffectImpl { if (new ModeChoiceSourceCondition("Dragons").apply(game, source)) { if (abilityToModify instanceof SpellAbility) { if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { - for (Mode mode : abilityToModify.getModes().getSelectedModes()) { + for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { + Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetUUID : target.getTargets()) { if (targetUUID.equals(source.getControllerId())) { diff --git a/Mage.Sets/src/mage/sets/kaladesh/CapturedByTheConsulate.java b/Mage.Sets/src/mage/sets/kaladesh/CapturedByTheConsulate.java index 5de6ebe9bdc..bb0eb4cc8d2 100644 --- a/Mage.Sets/src/mage/sets/kaladesh/CapturedByTheConsulate.java +++ b/Mage.Sets/src/mage/sets/kaladesh/CapturedByTheConsulate.java @@ -141,7 +141,8 @@ class CapturedByTheConsulateTriggeredAbility extends TriggeredAbilityImpl { } if (stackObject != null) { int numberOfTargets = 0; - for (Mode mode : stackObject.getStackAbility().getModes().getSelectedModes()) { + for (UUID modeId : stackObject.getStackAbility().getModes().getSelectedModes()) { + Mode mode = stackObject.getStackAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { numberOfTargets += target.getTargets().size(); } diff --git a/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java b/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java index 9aa89e0b2f2..533925a5786 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java +++ b/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java @@ -135,7 +135,8 @@ class PsychicRebuttalPredicate implements ObjectPlayerPredicate possibleTargets = target.possibleTargets(source.getSourceId(), source.getControllerId(), game); diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AccursedWitch.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AccursedWitch.java index bc42294c7f1..6e0f6c19ae0 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AccursedWitch.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AccursedWitch.java @@ -140,7 +140,8 @@ class AccursedWitchSpellsCostReductionEffect extends CostModificationEffectImpl public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { - for (Mode mode : abilityToModify.getModes().getSelectedModes()) { + for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { + Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetUUID : target.getTargets()) { Permanent permanent = game.getPermanent(targetUUID); diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/InfectiousCurse.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/InfectiousCurse.java index 2cc858e4bb6..03e76ef9b6e 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/InfectiousCurse.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/InfectiousCurse.java @@ -155,7 +155,8 @@ class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl { public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { if (source.getControllerId().equals(abilityToModify.getControllerId())) { - for (Mode mode : abilityToModify.getModes().getSelectedModes()) { + for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { + Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetUUID : target.getTargets()) { Permanent enchantment = game.getPermanent(source.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/HinderingLight.java b/Mage.Sets/src/mage/sets/shardsofalara/HinderingLight.java index 7726f3ab806..6cfe4482004 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/HinderingLight.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/HinderingLight.java @@ -84,7 +84,8 @@ class HinderingLightPredicate implements ObjectPlayerPredicate { if (spell != null) { int numberOfTargets = 0; for (SpellAbility spellAbility : spell.getSpellAbilities()) { - for (Mode mode : spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { + Mode mode = spellAbility.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetId : target.getTargets()) { if (!targetId.equals(sourceId)) { return false; - } - else { + } else { numberOfTargets++; } } diff --git a/Mage.Sets/src/mage/sets/vintagemasters/KaerveksTorch.java b/Mage.Sets/src/mage/sets/vintagemasters/KaerveksTorch.java index 2af317e2e49..14b5866ca5f 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/KaerveksTorch.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/KaerveksTorch.java @@ -96,7 +96,8 @@ class KaerveksTorchCostIncreaseEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) { - for (Mode mode : abilityToModify.getModes().getSelectedModes()) { + for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { + Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetId : target.getTargets()) { if (targetId.equals(source.getSourceObject(game).getId())) { diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastDestroySpellsTest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastDestroySpellsTest.java index 57f34cbc672..792284f65ab 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastDestroySpellsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastDestroySpellsTest.java @@ -38,10 +38,6 @@ import org.mage.test.serverside.base.CardTestPlayerBaseAI; */ public class CastDestroySpellsTest extends CardTestPlayerBaseAI { - /** - * - * - */ @Test public void testOrzhovCharm() { // Choose one - @@ -58,6 +54,8 @@ public class CastDestroySpellsTest extends CardTestPlayerBaseAI { // Cycling abilities you activate cost you up to {2} less to activate. addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Orzhov Charm", "Silvercoat Lion"); + setModeChoice(playerA, "2"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/modal/OneOrBothTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/modal/OneOrBothTest.java index cee56e63951..52aef300aaf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/modal/OneOrBothTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/modal/OneOrBothTest.java @@ -49,8 +49,9 @@ public class OneOrBothTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox"); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Subtle Strike", "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Subtle Strike", "Pillarfield Ox"); setModeChoice(playerA, "1"); + setModeChoice(playerA, null); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -72,6 +73,7 @@ public class OneOrBothTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Subtle Strike", "Pillarfield Ox"); setModeChoice(playerA, "2"); + setModeChoice(playerA, null); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java index 195666c6097..727efe0738b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java @@ -39,20 +39,22 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class BrutalExpulsionTest extends CardTestPlayerBase { /** - * Brutal Expulsion targeting Gideon, Ally of Zendikar. Gideon has 3 loyalty. Brutal Expulsion resolves, - * leaves 1 loyalty. I attack Gideon for 1 with a Scion token, Gideon dies. Instead of going to graveyard, - * Expulsion sends Gideon to exile. However, in game Gideon went to graveyard. + * Brutal Expulsion targeting Gideon, Ally of Zendikar. Gideon has 3 + * loyalty. Brutal Expulsion resolves, leaves 1 loyalty. I attack Gideon for + * 1 with a Scion token, Gideon dies. Instead of going to graveyard, + * Expulsion sends Gideon to exile. However, in game Gideon went to + * graveyard. */ @Test public void testPlaneswalkerExile() { // Choose one or both // - Return target spell or creature to its owner's hand; // or Brutal Expulsion deals 2 damage to target creature or planeswalker. If that permanent would be put into a graveyard this turn, exile it instead. - addCard(Zone.HAND, playerA, "Brutal Expulsion"); + addCard(Zone.HAND, playerA, "Brutal Expulsion"); // {2}{U}{R} // Shock deals 2 damage to target creature or player. - addCard(Zone.HAND, playerA, "Shock"); - addCard(Zone.BATTLEFIELD, playerA, "Island", 4); - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + addCard(Zone.HAND, playerA, "Shock"); // {R} + addCard(Zone.BATTLEFIELD, playerA, "Island", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); // Planeswalker with 4 loyalty. addCard(Zone.BATTLEFIELD, playerB, "Gideon, Ally of Zendikar"); @@ -60,12 +62,12 @@ public class BrutalExpulsionTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brutal Expulsion", playerB); setModeChoice(playerA, "2"); setModeChoice(playerA, null); - setChoice(playerA, "Yes"); + setChoice(playerA, "Yes"); // Redirect to planeswalker - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", playerB); - setChoice(playerA, "Yes"); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Shock", playerB); + setChoice(playerA, "Yes"); // Redirect to planeswalker - setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + setStopAt(1, PhaseStep.END_COMBAT); execute(); assertPermanentCount(playerB, "Gideon, Ally of Zendikar", 0); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index fd3b5ba7906..a8856084e0b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -287,7 +287,8 @@ public class TestPlayer implements Player { } UUID modeId = ability.getModes().getModeId(modeNr); - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID currentModeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(currentModeId); if (mode.getId().equals(modeId)) { selectedMode = mode; ability.getModes().setActiveMode(mode); diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 65f1095d378..c79e37f28bc 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -306,7 +306,8 @@ public abstract class AbilityImpl implements Ability { && game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, getId(), getSourceId(), getControllerId()), this)) { return false; } - for (Mode mode : this.getModes().getSelectedModes()) { + for (UUID modeId : this.getModes().getSelectedModes()) { + Mode mode = this.getModes().get(modeId); this.getModes().setActiveMode(mode); //20121001 - 601.2c // 601.2c The player announces his or her choice of an appropriate player, object, or zone for @@ -1060,7 +1061,8 @@ public abstract class AbilityImpl implements Ability { } } else if (object instanceof Spell && ((Spell) object).getSpellAbility().getModes().size() > 1) { Modes spellModes = ((Spell) object).getSpellAbility().getModes(); - for (Mode selectedMode : spellModes.getSelectedModes()) { + for (UUID selectedModeId : spellModes.getSelectedModes()) { + Mode selectedMode = spellModes.get(selectedModeId); int item = 0; for (Mode mode : spellModes.values()) { item++; diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java index 7ac07f93681..6f1ea6502a3 100644 --- a/Mage/src/main/java/mage/abilities/Modes.java +++ b/Mage/src/main/java/mage/abilities/Modes.java @@ -49,7 +49,7 @@ import mage.target.common.TargetOpponent; public class Modes extends LinkedHashMap { private Mode currentMode; // the current mode of the selected modes - private final ArrayList selectedModes = new ArrayList<>(); + private final ArrayList selectedModes = new ArrayList<>(); private int minModes; private int maxModes; private TargetController modeChooser; @@ -61,7 +61,7 @@ public class Modes extends LinkedHashMap { this.put(currentMode.getId(), currentMode); this.minModes = 1; this.maxModes = 1; - this.selectedModes.add(currentMode); + this.selectedModes.add(currentMode.getId()); this.modeChooser = TargetController.YOU; this.eachModeOnlyOnce = false; this.eachModeMoreThanOnce = false; @@ -74,21 +74,8 @@ public class Modes extends LinkedHashMap { this.minModes = modes.minModes; this.maxModes = modes.maxModes; - if (modes.size() == 1) { - this.currentMode = values().iterator().next(); - this.selectedModes.add(currentMode); - } else { - // probably there is still a problem with copying modes with the same mode selected multiple times. - for (Mode selectedMode : modes.getSelectedModes()) { - Mode copiedMode = selectedMode.copy(); - this.selectedModes.add(copiedMode); - if (modes.getSelectedModes().size() == 1) { - this.currentMode = copiedMode; - } else if (selectedMode.equals(modes.getMode())) { - this.currentMode = copiedMode; - } - } - } + this.currentMode = values().iterator().next(); + selectedModes.addAll(modes.getSelectedModes()); this.modeChooser = modes.modeChooser; this.eachModeOnlyOnce = modes.eachModeOnlyOnce; this.eachModeMoreThanOnce = modes.eachModeMoreThanOnce; @@ -113,7 +100,7 @@ public class Modes extends LinkedHashMap { return null; } - public ArrayList getSelectedModes() { + public ArrayList getSelectedModes() { return selectedModes; } @@ -142,7 +129,7 @@ public class Modes extends LinkedHashMap { } public void setActiveMode(Mode mode) { - if (selectedModes.contains(mode)) { + if (selectedModes.contains(mode.getId())) { this.currentMode = mode; } } @@ -172,7 +159,7 @@ public class Modes extends LinkedHashMap { for (Mode mode : this.values()) { if ((!isEachModeOnlyOnce() || onceSelectedModes == null || !onceSelectedModes.contains(mode.getId())) && mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { - this.selectedModes.add(mode.copy()); + this.selectedModes.add(mode.getId()); } } if (isEachModeOnlyOnce()) { @@ -209,7 +196,7 @@ public class Modes extends LinkedHashMap { } return this.selectedModes.size() >= this.getMinModes(); } - this.selectedModes.add(choice.copy()); + this.selectedModes.add(choice.getId()); if (currentMode == null) { currentMode = choice; } @@ -222,7 +209,7 @@ public class Modes extends LinkedHashMap { if (currentMode == null) { this.selectedModes.clear(); Mode copiedMode = this.values().iterator().next().copy(); - this.selectedModes.add(copiedMode); + this.selectedModes.add(copiedMode.getId()); this.setActiveMode(copiedMode); } if (isEachModeOnlyOnce()) { @@ -238,9 +225,9 @@ public class Modes extends LinkedHashMap { * @param source * @param game */ - private void setAlreadySelectedModes(ArrayList selectedModes, Ability source, Game game) { - for (Mode mode : selectedModes) { - String key = getKey(source, game, mode.getId()); + private void setAlreadySelectedModes(ArrayList selectedModes, Ability source, Game game) { + for (UUID modeId : selectedModes) { + String key = getKey(source, game, modeId); game.getState().setValue(key, true); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java index 43dd5593277..8884c6c1414 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ChangeATargetOfTargetSpellAbilityToSourceEffect.java @@ -51,7 +51,8 @@ public class ChangeATargetOfTargetSpellAbilityToSourceEffect extends OneShotEffe } else { return false; } - for (Mode mode : sourceAbility.getModes().getSelectedModes()) { + for (UUID modeId : sourceAbility.getModes().getSelectedModes()) { + Mode mode = sourceAbility.getModes().get(modeId); targets.addAll(mode.getTargets()); } @@ -102,12 +103,10 @@ public class ChangeATargetOfTargetSpellAbilityToSourceEffect extends OneShotEffe } if (oldTargetName != null) { game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTargetName + " to " + sourceObject.getLogName()); + } else if (twoTimesTarget) { + game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName()); } else { - if (twoTimesTarget) { - game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName()); - } else { - game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName()); - } + game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName()); } return true; } diff --git a/Mage/src/main/java/mage/abilities/keyword/HeroicAbility.java b/Mage/src/main/java/mage/abilities/keyword/HeroicAbility.java index bbd8ed567db..083a80484b7 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HeroicAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HeroicAbility.java @@ -1,4 +1,4 @@ - /* +/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are @@ -82,7 +82,8 @@ public class HeroicAbility extends TriggeredAbilityImpl { private boolean checkSpell(Spell spell, Game game) { if (spell != null) { SpellAbility sa = spell.getSpellAbility(); - for (Mode mode : sa.getModes().getSelectedModes()) { + for (UUID modeId : sa.getModes().getSelectedModes()) { + Mode mode = sa.getModes().get(modeId); for (Target target : mode.getTargets()) { if (!target.isNotTarget() && target.getTargets().contains(this.getSourceId())) { return true; diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/NumberOfTargetsPredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/NumberOfTargetsPredicate.java index 47bfd2ed07c..3653b268a78 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/NumberOfTargetsPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/NumberOfTargetsPredicate.java @@ -27,6 +27,7 @@ */ package mage.filter.predicate.mageobject; +import java.util.UUID; import mage.MageObject; import mage.abilities.Mode; import mage.filter.predicate.Predicate; @@ -51,7 +52,8 @@ public class NumberOfTargetsPredicate implements Predicate { StackObject stackObject = game.getState().getStack().getStackObject(input.getId()); if (stackObject != null) { int numberOfTargets = 0; - for (Mode mode : stackObject.getStackAbility().getModes().getSelectedModes()) { + for (UUID modeId : stackObject.getStackAbility().getModes().getSelectedModes()) { + Mode mode = stackObject.getStackAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { numberOfTargets += target.getTargets().size(); } diff --git a/Mage/src/main/java/mage/filter/predicate/other/TargetsPermanentPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/TargetsPermanentPredicate.java index aad5bb551b6..7dc12d7984d 100644 --- a/Mage/src/main/java/mage/filter/predicate/other/TargetsPermanentPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/other/TargetsPermanentPredicate.java @@ -54,7 +54,8 @@ public class TargetsPermanentPredicate implements ObjectSourcePlayerPredicate input, Game game) { StackObject object = game.getStack().getStackObject(input.getObject().getId()); if (object != null) { - for (Mode mode : object.getStackAbility().getModes().getSelectedModes()) { + for (UUID modeId : object.getStackAbility().getModes().getSelectedModes()) { + Mode mode = object.getStackAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetId : target.getTargets()) { Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); diff --git a/Mage/src/main/java/mage/game/GameState.java b/Mage/src/main/java/mage/game/GameState.java index 2e48c954ce0..eb553340685 100644 --- a/Mage/src/main/java/mage/game/GameState.java +++ b/Mage/src/main/java/mage/game/GameState.java @@ -314,7 +314,8 @@ public class GameState implements Serializable, Copyable { for (StackObject spell : stack) { sb.append(spell.getControllerId()).append(spell.getName()); sb.append(spell.getStackAbility().toString()); - for (Mode mode : spell.getStackAbility().getModes().getSelectedModes()) { + for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) { + Mode mode = spell.getStackAbility().getModes().get(modeId); if (!mode.getTargets().isEmpty()) { sb.append("targets"); for (Target target : mode.getTargets()) { @@ -366,7 +367,8 @@ public class GameState implements Serializable, Copyable { for (StackObject spell : stack) { sb.append(spell.getControllerId()).append(spell.getName()); sb.append(spell.getStackAbility().toString()); - for (Mode mode : spell.getStackAbility().getModes().getSelectedModes()) { + for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) { + Mode mode = spell.getStackAbility().getModes().get(modeId); if (!mode.getTargets().isEmpty()) { sb.append("targets"); for (Target target : mode.getTargets()) { @@ -784,7 +786,8 @@ public class GameState implements Serializable, Copyable { public void addAbility(Ability ability, MageObject attachedTo) { if (ability instanceof StaticAbility) { - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); for (Effect effect : mode.getEffects()) { if (effect instanceof ContinuousEffect) { addEffect((ContinuousEffect) effect, ability); @@ -806,7 +809,8 @@ public class GameState implements Serializable, Copyable { */ public void addAbility(Ability ability, UUID sourceId, Card attachedTo) { if (ability instanceof StaticAbility) { - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); for (Effect effect : mode.getEffects()) { if (effect instanceof ContinuousEffect) { addEffect((ContinuousEffect) effect, sourceId, ability); diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index b6bc9b98356..f587a9ed7ab 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -210,7 +210,8 @@ public class Spell extends StackObjImpl implements Card { if (notTargeted || legalParts) { for (SpellAbility spellAbility : this.spellAbilities) { if (spellAbilityHasLegalParts(spellAbility, game)) { - for (Mode mode : spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { + Mode mode = spellAbility.getModes().get(modeId); spellAbility.getModes().setActiveMode(mode); if (mode.getTargets().stillLegal(spellAbility, game)) { if (!spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { @@ -283,7 +284,8 @@ public class Spell extends StackObjImpl implements Card { private boolean hasTargets(SpellAbility spellAbility, Game game) { if (spellAbility.getModes().getSelectedModes().size() > 1) { - for (Mode mode : spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { + Mode mode = spellAbility.getModes().get(modeId); if (!mode.getTargets().isEmpty()) { return true; } @@ -299,7 +301,8 @@ public class Spell extends StackObjImpl implements Card { if (spellAbility.getModes().getSelectedModes().size() > 1) { boolean targetedMode = false; boolean legalTargetedMode = false; - for (Mode mode : spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { + Mode mode = spellAbility.getModes().get(modeId); if (mode.getTargets().size() > 0) { targetedMode = true; if (mode.getTargets().stillLegal(spellAbility, game)) { diff --git a/Mage/src/main/java/mage/game/stack/StackObjImpl.java b/Mage/src/main/java/mage/game/stack/StackObjImpl.java index 2286fd06ae5..d37d6f78a97 100644 --- a/Mage/src/main/java/mage/game/stack/StackObjImpl.java +++ b/Mage/src/main/java/mage/game/stack/StackObjImpl.java @@ -117,7 +117,8 @@ public abstract class StackObjImpl implements StackObject { } for (Ability ability : objectAbilities) { // Some spells can have more than one mode - for (Mode mode : ability.getModes().getSelectedModes()) { + for (UUID modeId : ability.getModes().getSelectedModes()) { + Mode mode = ability.getModes().get(modeId); ability.getModes().setActiveMode(mode); oldTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game)); for (Target target : mode.getTargets()) { @@ -210,8 +211,7 @@ public abstract class StackObjImpl implements StackObject { again = true; } } else // if possible add the alternate Target - it may not be included in the old definition nor in the already selected targets of the new definition - { - if (newTarget.getTargets().contains(tempTarget.getFirstTarget()) || target.getTargets().contains(tempTarget.getFirstTarget())) { + if (newTarget.getTargets().contains(tempTarget.getFirstTarget()) || target.getTargets().contains(tempTarget.getFirstTarget())) { if (targetController.isHuman()) { if (targetController.chooseUse(Outcome.Benefit, "This target was already selected from origin spell. Reset to original target?", ability, game)) { // use previous target no target was selected @@ -240,7 +240,6 @@ public abstract class StackObjImpl implements StackObject { // valid target was selected, add it to the new target definition newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false); } - } } while (again && targetController.canRespond()); } } // keep the target diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 6a045a8e48b..8b5ca4049d4 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2870,7 +2870,7 @@ public abstract class PlayerImpl implements Player, Serializable { for (Mode mode : option.getModes().values()) { Ability newOption = option.copy(); newOption.getModes().getSelectedModes().clear(); - newOption.getModes().getSelectedModes().add(mode); + newOption.getModes().getSelectedModes().add(mode.getId()); newOption.getModes().setActiveMode(mode); if (newOption.getTargets().getUnchosen().size() > 0) { if (newOption.getManaCosts().getVariableCosts().size() > 0) { diff --git a/Mage/src/main/java/mage/target/common/TargetCreatureOrPlaneswalker.java b/Mage/src/main/java/mage/target/common/TargetCreatureOrPlaneswalker.java index 3e58a0523eb..c075c54d4fa 100644 --- a/Mage/src/main/java/mage/target/common/TargetCreatureOrPlaneswalker.java +++ b/Mage/src/main/java/mage/target/common/TargetCreatureOrPlaneswalker.java @@ -25,10 +25,13 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.target.common; +import java.util.UUID; +import mage.abilities.Ability; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; +import mage.game.Game; +import mage.players.Player; import mage.target.TargetPermanent; /** @@ -38,7 +41,7 @@ import mage.target.TargetPermanent; public class TargetCreatureOrPlaneswalker extends TargetPermanent { public TargetCreatureOrPlaneswalker() { - this(1, 1 ,new FilterCreatureOrPlaneswalkerPermanent(), false); + this(1, 1, new FilterCreatureOrPlaneswalkerPermanent(), false); } public TargetCreatureOrPlaneswalker(int minNumTargets, int maxNumTargets, FilterCreatureOrPlaneswalkerPermanent filter, boolean notTarget) { @@ -55,4 +58,16 @@ public class TargetCreatureOrPlaneswalker extends TargetPermanent { return new TargetCreatureOrPlaneswalker(this); } + @Override + public boolean isLegal(Ability source, Game game) { + for (UUID playerId : targets.keySet()) { + Player targetPlayer = game.getPlayer(playerId); + if (targetPlayer != null) { + // there seems to be no possibility to add more predicates for theplayer so return here true + return true; + } + } + return super.isLegal(source, game); //To change body of generated methods, choose Tools | Templates. + } + } diff --git a/Mage/src/main/java/mage/util/TargetAddress.java b/Mage/src/main/java/mage/util/TargetAddress.java index 57bdddc23b4..80c5724676d 100644 --- a/Mage/src/main/java/mage/util/TargetAddress.java +++ b/Mage/src/main/java/mage/util/TargetAddress.java @@ -70,7 +70,7 @@ public class TargetAddress { protected Iterator spellAbilityIterator; protected Integer lastSpellAbilityIndex = null; - protected Iterator modeIterator = null; + protected Iterator modeIterator = null; protected Modes modes = null; protected UUID lastMode = null; protected Iterator targetIterator = null; @@ -127,7 +127,7 @@ public class TargetAddress { } if (modeIterator != null && modeIterator.hasNext()) { - lastMode = modeIterator.next().getId(); + lastMode = modeIterator.next(); targetIterator = modes.get(lastMode).getTargets().iterator(); } else { lastMode = null;