diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index d155931867..12a189a2ac 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -280,7 +280,7 @@ public class CardView extends SimpleCardView { Spell spell = (Spell) card; for (SpellAbility spellAbility: spell.getSpellAbilities()) { for(UUID modeId : spellAbility.getModes().getSelectedModes()) { - spellAbility.getModes().setMode(spellAbility.getModes().get(modeId)); + spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().size() > 0) { setTargets(spellAbility.getTargets()); } @@ -290,7 +290,7 @@ public class CardView extends SimpleCardView { if (spell.getSpellAbility().isModal()) { Modes modes = spell.getSpellAbility().getModes(); for(UUID modeId : modes.getSelectedModes()) { - modes.setMode(modes.get(modeId)); + modes.setActiveMode(modeId); this.rules.add("Chosen mode: " + spell.getSpellAbility().getEffects().getText(modes.get(modeId))+""); } } diff --git a/Mage.Common/src/mage/view/StackAbilityView.java b/Mage.Common/src/mage/view/StackAbilityView.java index 8a5dae7d00..4388c3df78 100644 --- a/Mage.Common/src/mage/view/StackAbilityView.java +++ b/Mage.Common/src/mage/view/StackAbilityView.java @@ -98,7 +98,7 @@ public class StackAbilityView extends CardView { private void updateTargets(Game game, StackAbility ability) { List names = new ArrayList<>(); for(UUID modeId : ability.getModes().getSelectedModes()) { - ability.getModes().setMode(ability.getModes().get(modeId)); + ability.getModes().setActiveMode(modeId); if (ability.getTargets().size() > 0) { setTargets(ability.getTargets()); } else { @@ -129,7 +129,7 @@ public class StackAbilityView extends CardView { if (ability.isModal()) { Modes modes = ability.getModes(); for(UUID modeId : modes.getSelectedModes()) { - modes.setMode(modes.get(modeId)); + modes.setActiveMode(modeId); this.rules.add("Chosen mode: " + ability.getEffects().getText(modes.get(modeId))+""); } } diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 0d6f71daf5..16a8490c32 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -69,7 +69,6 @@ import mage.game.command.Emblem; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentCard; import mage.game.stack.Spell; import mage.game.stack.StackAbility; import mage.players.Player; @@ -263,7 +262,7 @@ public abstract class AbilityImpl implements Ability { // TODO: Because all (non targeted) choices have to be done during resolution // this has to be removed, if all using effects are changed for (UUID modeId :this.getModes().getSelectedModes()) { - this.getModes().setMode(this.getModes().get(modeId)); + this.getModes().setActiveMode(modeId); if (getChoices().size() > 0 && getChoices().choose(game, this) == false) { logger.debug("activate failed - choice"); return false; @@ -302,7 +301,7 @@ public abstract class AbilityImpl implements Ability { String announceString = handleOtherXCosts(game, controller); for (UUID modeId :this.getModes().getSelectedModes()) { - this.getModes().setMode(this.getModes().get(modeId)); + this.getModes().setActiveMode(modeId); //20121001 - 601.2c // 601.2c The player announces his or her choice of an appropriate player, object, or zone for // each target the spell requires. A spell may require some targets only if an alternative or @@ -1037,7 +1036,7 @@ public abstract class AbilityImpl implements Ability { for (Mode mode : spellModes.values()) { item++; if (spellModes.getSelectedModes().contains(mode.getId())) { - spellModes.setMode(mode); + spellModes.setActiveMode(mode.getId()); sb.append(" (mode ").append(item).append(")"); sb.append(getTargetDescriptionForLog(getTargets(), game)); } diff --git a/Mage/src/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/mage/abilities/ActivatedAbilityImpl.java index 7637d5e930..e5e1b819a5 100644 --- a/Mage/src/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/mage/abilities/ActivatedAbilityImpl.java @@ -43,6 +43,7 @@ import mage.cards.Card; import mage.constants.AsThoughEffectType; import mage.constants.TargetController; import mage.game.Game; +import mage.game.permanent.Permanent; /** @@ -174,13 +175,21 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa if (! game.getPlayer(controllerId).hasOpponent(playerId, game)){ return false; } - break; - + break; case YOU: if(!controlsAbility(playerId, game)){ return false; } break; + case CONTROLLER_ATTACHED_TO: + Permanent enchantment = game.getPermanent(getSourceId()); + if (enchantment != null && enchantment.getAttachedTo() != null) { + Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); + if (enchanted != null && enchanted.getControllerId().equals(playerId)) { + break; + } + } + return false; } //20091005 - 602.5d/602.5e if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId) || diff --git a/Mage/src/mage/abilities/Modes.java b/Mage/src/mage/abilities/Modes.java index 0d50987f57..1ea0c5241a 100644 --- a/Mage/src/mage/abilities/Modes.java +++ b/Mage/src/mage/abilities/Modes.java @@ -109,10 +109,24 @@ public class Modes extends LinkedHashMap { return this.modeChooser; } + public void setActiveMode(UUID modeId) { + if (selectedModes.contains(modeId)) { + this.modeId = modeId; + } + } + public void setMode(Mode mode) { if (this.containsKey(mode.getId())) { this.modeId = mode.getId(); this.selectedModes.add(mode.getId()); + Set copySelectedModes = new LinkedHashSet<>(); + copySelectedModes.addAll(selectedModes); + selectedModes.clear(); + for (UUID basicModeId: this.keySet()) { + if (copySelectedModes.contains(basicModeId)) { + selectedModes.add(basicModeId); + } + } } } @@ -167,7 +181,6 @@ public class Modes extends LinkedHashMap { return this.selectedModes.size() >= this.getMinModes(); } setMode(choice); - this.selectedModes.add(choice.getId()); } return true; } diff --git a/Mage/src/mage/abilities/costs/CostsImpl.java b/Mage/src/mage/abilities/costs/CostsImpl.java index da4c3b0de6..a2624f3f29 100644 --- a/Mage/src/mage/abilities/costs/CostsImpl.java +++ b/Mage/src/mage/abilities/costs/CostsImpl.java @@ -66,9 +66,13 @@ public class CostsImpl extends ArrayList implements Costs StringBuilder sbText = new StringBuilder(); for (T cost: this) { String text = cost.getText(); - sbText.append(Character.toUpperCase(text.charAt(0))).append(text.substring(1)).append(", "); + if (text != null && !text.isEmpty()) { + sbText.append(Character.toUpperCase(text.charAt(0))).append(text.substring(1)).append(", "); + } + } + if (sbText.length() > 1){ + sbText.setLength(sbText.length() - 2); } - sbText.setLength(sbText.length() - 2); return sbText.toString(); } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java index cc01c1a616..4da3a67339 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java @@ -27,11 +27,14 @@ */ package mage.abilities.effects.common; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; +import static mage.constants.Zone.BATTLEFIELD; +import static mage.constants.Zone.GRAVEYARD; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -67,9 +70,9 @@ public class ReturnToHandSourceEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Card card = game.getCard(source.getSourceId()); - if (card != null) { - switch (game.getState().getZone(card.getId())) { + MageObject mageObject = source.getSourceObjectIfItStillExists(game); + if (mageObject != null) { + switch (game.getState().getZone(mageObject.getId())) { case BATTLEFIELD: Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { @@ -77,12 +80,13 @@ public class ReturnToHandSourceEffect extends OneShotEffect { } break; case GRAVEYARD: + Card card = (Card) mageObject; if (!fromBattlefieldOnly) { return controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); } - } - } + } + return true; } return false; } diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index a6e9f3db5c..5a85393e51 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -190,7 +190,7 @@ public class Spell implements StackObject, Card { for(SpellAbility spellAbility: this.spellAbilities) { if (spellAbilityHasLegalParts(spellAbility, game)) { for (UUID modeId :spellAbility.getModes().getSelectedModes()) { - spellAbility.getModes().setMode(spellAbility.getModes().get(modeId)); + spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().stillLegal(spellAbility, game)) { if (!spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { updateOptionalCosts(index); @@ -269,7 +269,7 @@ public class Spell implements StackObject, Card { boolean targetedMode = false; boolean legalTargetedMode = false; for (UUID modeId :spellAbility.getModes().getSelectedModes()) { - spellAbility.getModes().setMode(spellAbility.getModes().get(modeId)); + spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().size() > 0) { targetedMode = true; if (spellAbility.getTargets().stillLegal(spellAbility, game)) {