diff --git a/Mage.Sets/src/mage/sets/alarareborn/ClovenCasting.java b/Mage.Sets/src/mage/sets/alarareborn/ClovenCasting.java index 9e04db2d821..8e9898cf950 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/ClovenCasting.java +++ b/Mage.Sets/src/mage/sets/alarareborn/ClovenCasting.java @@ -64,9 +64,6 @@ public class ClovenCasting extends CardImpl { super(ownerId, 86, "Cloven Casting", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{U}{R}"); this.expansionSetCode = "ARB"; - - - // Whenever you cast a multicolored instant or sorcery spell, you may pay {1}. If you do, copy that spell. You may choose new targets for the copy. this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(new ClovenCastingEffect(), new GenericManaCost(1)), filter, true, true)); @@ -97,9 +94,7 @@ class ClovenCastingEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); Player player = game.getPlayer(source.getControllerId()); @@ -117,4 +112,4 @@ class ClovenCastingEffect extends OneShotEffect { public ClovenCastingEffect copy() { return new ClovenCastingEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/KorCastigator.java b/Mage.Sets/src/mage/sets/battleforzendikar/KorCastigator.java index 2595f18b8b3..18ea9c1c136 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/KorCastigator.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/KorCastigator.java @@ -44,11 +44,11 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class KorCastigator extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Eldrazi Scions"); + private static final FilterCreaturePermanent FILTER = new FilterCreaturePermanent("Eldrazi Scions"); static { - filter.add(new SubtypePredicate("Eldrazi")); - filter.add(new SubtypePredicate("Scion")); + FILTER.add(new SubtypePredicate("Eldrazi")); + FILTER.add(new SubtypePredicate("Scion")); } public KorCastigator(UUID ownerId) { @@ -61,7 +61,7 @@ public class KorCastigator extends CardImpl { this.toughness = new MageInt(1); // Kor Castigator can't be blocked by Eldrazi Scions. - this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(FILTER, Duration.WhileOnBattlefield))); } public KorCastigator(final KorCastigator card) { diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java index e20744b3694..e635f2d6de2 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java @@ -103,13 +103,17 @@ class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl { Spell spell = game.getStack().getSpell(event.getTargetId()); if (isControlledInstantOrSorcery(spell)) { boolean targetsSource = false; - for (Mode mode : spell.getSpellAbility().getModes().getSelectedModes()) { - for (Target target : mode.getTargets()) { - for (UUID targetId : target.getTargets()) { - if (targetId.equals(getSourceId())) { - targetsSource = true; - } else { - return false; + for (Ability ability : spell.getSpellAbilities()) { + for (Mode mode : ability.getModes().getSelectedModes()) { + for (Target target : mode.getTargets()) { + if (!target.isNotTarget()) { + for (UUID targetId : target.getTargets()) { + if (targetId.equals(getSourceId())) { + targetsSource = true; + } else { + return false; + } + } } } } @@ -159,14 +163,17 @@ class ZadaHedronGrinderEffect extends OneShotEffect { } Player controller = game.getPlayer(source.getControllerId()); if (spell != null && controller != null) { + // search the target that targets source Target usedTarget = null; setUsedTarget: - for (Mode mode : spell.getSpellAbility().getModes().getSelectedModes()) { - for (Target target : mode.getTargets()) { - if (target.getFirstTarget().equals(source.getSourceId())) { - usedTarget = target.copy(); - usedTarget.clearChosen(); - break setUsedTarget; + for (Ability ability : spell.getSpellAbilities()) { + for (Mode mode : ability.getModes().getSelectedModes()) { + for (Target target : mode.getTargets()) { + if (!target.isNotTarget() && target.getFirstTarget().equals(source.getSourceId())) { + usedTarget = target.copy(); + usedTarget.clearChosen(); + break setUsedTarget; + } } } } @@ -175,7 +182,7 @@ class ZadaHedronGrinderEffect extends OneShotEffect { } for (Permanent creature : game.getState().getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { if (!creature.getId().equals(source.getSourceId()) && usedTarget.canTarget(source.getControllerId(), creature.getId(), source, game)) { - Spell copy = spell.copySpell(); + Spell copy = spell.copySpell(source.getControllerId()); setTarget: for (Mode mode : spell.getSpellAbility().getModes().getSelectedModes()) { for (Target target : mode.getTargets()) { @@ -188,8 +195,6 @@ class ZadaHedronGrinderEffect extends OneShotEffect { } } } - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); game.getStack().push(copy); String activateMessage = copy.getActivatedMessage(game); if (activateMessage.startsWith(" casts ")) { diff --git a/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java b/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java index f1d4582bf77..3f4b036bedd 100644 --- a/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java +++ b/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java @@ -116,9 +116,7 @@ class RikuOfTwoReflectionsCopyEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId());; game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); Player player = game.getPlayer(source.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/commander/WildRicochet.java b/Mage.Sets/src/mage/sets/commander/WildRicochet.java index 7c6f93ea12a..b642260c35b 100644 --- a/Mage.Sets/src/mage/sets/commander/WildRicochet.java +++ b/Mage.Sets/src/mage/sets/commander/WildRicochet.java @@ -60,7 +60,6 @@ public class WildRicochet extends CardImpl { super(ownerId, 139, "Wild Ricochet", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{R}{R}"); this.expansionSetCode = "CMD"; - // You may choose new targets for target instant or sorcery spell. Then copy that spell. You may choose new targets for the copy. this.getSpellAbility().addEffect(new WildRicochetEffect()); this.getSpellAbility().addTarget(new TargetStackObject(filter)); @@ -96,9 +95,7 @@ class WildRicochetEffect extends OneShotEffect { spell.chooseNewTargets(game, you.getId()); } if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId());; game.getStack().push(copy); if (you != null && you.chooseUse(Outcome.Benefit, "Do you wish to choose new targets for the copied " + spell.getName() + "?", source, game)) { return copy.chooseNewTargets(game, you.getId()); diff --git a/Mage.Sets/src/mage/sets/commander2014/MaliciousAffliction.java b/Mage.Sets/src/mage/sets/commander2014/MaliciousAffliction.java index c144bd67c8e..3325909cc3d 100644 --- a/Mage.Sets/src/mage/sets/commander2014/MaliciousAffliction.java +++ b/Mage.Sets/src/mage/sets/commander2014/MaliciousAffliction.java @@ -30,18 +30,14 @@ package mage.sets.commander2014; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility; import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.MorbidCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CastSourceTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; @@ -49,7 +45,6 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.game.stack.Spell; -import mage.game.stack.StackObject; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; @@ -69,7 +64,6 @@ public class MaliciousAffliction extends CardImpl { super(ownerId, 25, "Malicious Affliction", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{B}{B}"); this.expansionSetCode = "C14"; - // Morbid - When you cast Malicious Affliction, if a creature died this turn, you may copy Malicious Affliction and may choose a new target for the copy. Ability ability = new ConditionalTriggeredAbility( new CastSourceTriggeredAbility(new CopySourceSpellEffect(), true), @@ -112,9 +106,7 @@ class CopySourceSpellEffect extends OneShotEffect { if (controller != null) { Spell spell = game.getStack().getSpell(source.getSourceId()); if (spell != null) { - Spell spellCopy = spell.copySpell(); - spellCopy.setCopiedSpell(true); - spellCopy.setControllerId(source.getControllerId()); + Spell spellCopy = spell.copySpell(source.getControllerId());; game.getStack().push(spellCopy); spellCopy.chooseNewTargets(game, controller.getId()); String activateMessage = spellCopy.getActivatedMessage(game); @@ -132,4 +124,4 @@ class CopySourceSpellEffect extends OneShotEffect { public CopySourceSpellEffect copy() { return new CopySourceSpellEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java index 297f33647d9..ad3f964a8b2 100644 --- a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java +++ b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java @@ -28,9 +28,6 @@ package mage.sets.darkascension; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.TriggeredAbilityImpl; @@ -38,7 +35,9 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; @@ -63,7 +62,6 @@ public class CurseOfEchoes extends CardImpl { this.subtype.add("Aura"); this.subtype.add("Curse"); - // Enchant player TargetPlayer auraTarget = new TargetPlayer(); this.getSpellAbility().addTarget(auraTarget); @@ -149,13 +147,11 @@ class CurseOfEchoesEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { String chooseMessage = "Copy target spell? You may choose new targets for the copy."; - for (UUID playerId: game.getPlayerList()) { + for (UUID playerId : game.getPlayerList()) { if (!playerId.equals(spell.getControllerId())) { Player player = game.getPlayer(playerId); if (player.chooseUse(Outcome.Copy, chooseMessage, source, game)) { - Spell copy = spell.copySpell(); - copy.setControllerId(playerId); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId());; game.getStack().push(copy); copy.chooseNewTargets(game, playerId); } @@ -171,7 +167,7 @@ class CurseOfEchoesEffect extends OneShotEffect { return new CurseOfEchoesEffect(this); } - @Override + @Override public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); sb.append("Copy target ").append(mode.getTargets().get(0).getTargetName()).append(". You may choose new targets for the copy"); diff --git a/Mage.Sets/src/mage/sets/darkascension/IncreasingVengeance.java b/Mage.Sets/src/mage/sets/darkascension/IncreasingVengeance.java index c8eea72f273..f39db848230 100644 --- a/Mage.Sets/src/mage/sets/darkascension/IncreasingVengeance.java +++ b/Mage.Sets/src/mage/sets/darkascension/IncreasingVengeance.java @@ -28,13 +28,12 @@ package mage.sets.darkascension; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; +import mage.constants.*; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -64,7 +63,6 @@ public class IncreasingVengeance extends CardImpl { super(ownerId, 95, "Increasing Vengeance", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{R}{R}"); this.expansionSetCode = "DKA"; - // Copy target instant or sorcery spell you control. If Increasing Vengeance was cast from a graveyard, copy that spell twice instead. You may choose new targets for the copies. this.getSpellAbility().addEffect(new IncreasingVengeanceEffect()); Target target = new TargetSpell(filter); @@ -101,18 +99,14 @@ class IncreasingVengeanceEffect extends OneShotEffect { if (controller != null) { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); game.informPlayers(new StringBuilder(controller.getLogName()).append(copy.getActivatedMessage(game)).toString()); Spell sourceSpell = (Spell) game.getStack().getStackObject(source.getSourceId()); if (sourceSpell != null) { if (sourceSpell.getFromZone() == Zone.GRAVEYARD) { - copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); game.informPlayers(new StringBuilder(controller.getLogName()).append(copy.getActivatedMessage(game)).toString()); diff --git a/Mage.Sets/src/mage/sets/eventide/MirrorSheen.java b/Mage.Sets/src/mage/sets/eventide/MirrorSheen.java index 53d3ab2d22c..30ab806723b 100644 --- a/Mage.Sets/src/mage/sets/eventide/MirrorSheen.java +++ b/Mage.Sets/src/mage/sets/eventide/MirrorSheen.java @@ -52,11 +52,12 @@ import mage.target.TargetSpell; /** * * @author jeffwadsworth - + * */ public class MirrorSheen extends CardImpl { - + private static final FilterSpell filter = new FilterSpell(); + static { filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); filter.add(new TargetYouPredicate()); @@ -66,12 +67,11 @@ public class MirrorSheen extends CardImpl { super(ownerId, 105, "Mirror Sheen", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{U/R}{U/R}"); this.expansionSetCode = "EVE"; - // {1}{UR}{UR}: Copy target instant or sorcery spell that targets you. You may choose new targets for the copy. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MirrorSheenEffect(), new ManaCostsImpl("{1}{U/R}{U/R}")); ability.addTarget(new TargetSpell(filter)); this.addAbility(ability); - + } public MirrorSheen(final MirrorSheen card) { @@ -99,9 +99,7 @@ class MirrorSheenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(source.getFirstTarget()); if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); Player player = game.getPlayer(source.getControllerId()); @@ -144,4 +142,4 @@ class TargetYouPredicate implements ObjectPlayerPredicate */ public abstract class CopySpellForEachItCouldTargetEffect extends OneShotEffect { - + protected final FilterInPlay filter; public CopySpellForEachItCouldTargetEffect(FilterInPlay filter) { super(Outcome.Copy); - this.staticText = "copy the spell for each other "+filter.getMessage()+" that spell could target. Each copy targets a different one"; + this.staticText = "copy the spell for each other " + filter.getMessage() + " that spell could target. Each copy targets a different one"; this.filter = filter; } @@ -71,10 +71,12 @@ public abstract class CopySpellForEachItCouldTargetEffect ex } protected abstract Spell getSpell(Game game, Ability source); + protected abstract boolean changeTarget(Target target, Game game, Ability source); + protected abstract void modifyCopy(Spell copy, Game game, Ability source); - - protected void modifyCopy(Spell copy, T newTarget, Game game, Ability source){ + + protected void modifyCopy(Spell copy, T newTarget, Game game, Ability source) { modifyCopy(copy, game, source); } @@ -97,18 +99,17 @@ public abstract class CopySpellForEachItCouldTargetEffect ex targetsToBeChanged.add(addr); } } - + if (targetsToBeChanged.size() < 1) { return false; } // collect objects that can be targeted - Spell copy = spell.copySpell(); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); modifyCopy(copy, game, source); Target sampleTarget = targetsToBeChanged.iterator().next().getTarget(copy); sampleTarget.setNotTarget(true); - + Map> playerTargetCopyMap = new HashMap<>(); for (UUID objId : sampleTarget.possibleTargets(controller.getId(), game)) { MageItem obj = game.getObject(objId); @@ -116,9 +117,7 @@ public abstract class CopySpellForEachItCouldTargetEffect ex obj = game.getPlayer(objId); } if (obj != null) { - copy = spell.copySpell(); - copy.setCopiedSpell(true); - + copy = spell.copySpell(source.getControllerId()); try { modifyCopy(copy, (T) obj, game, source); if (!filter.match((T) obj, game)) { @@ -174,7 +173,7 @@ public abstract class CopySpellForEachItCouldTargetEffect ex // shortcut if there's only one possible target remaining if (targetCopyMap.size() > 1 - && target.canChoose(spell.getId(), player.getId(), game)) { + && target.canChoose(spell.getId(), player.getId(), game)) { player.choose(Outcome.Neutral, target, spell.getId(), game); } Collection chosenIds = target.getTargets(); @@ -205,8 +204,6 @@ public abstract class CopySpellForEachItCouldTargetEffect ex } } - - class CompoundFilter extends FilterImpl implements FilterInPlay { protected final FilterInPlay filterA; @@ -228,7 +225,7 @@ class CompoundFilter extends FilterImpl implements Filter public boolean match(T obj, Game game) { return (filterA == null || !filterA.match(obj, game)) - && (filterB == null + && (filterB == null || !filterB.match(obj, game)); } @@ -236,36 +233,35 @@ class CompoundFilter extends FilterImpl implements Filter public boolean match(T obj, UUID sourceId, UUID playerId, Game game) { return (filterA == null || !filterA.match(obj, sourceId, playerId, game)) - && (filterB == null + && (filterB == null || !filterB.match(obj, sourceId, playerId, game)); } @Override public CompoundFilter copy() { return new CompoundFilter(filterA == null ? null : filterA.copy(), - filterB == null ? null : filterB.copy(), - message); + filterB == null ? null : filterB.copy(), + message); } } - class TargetWithAdditionalFilter extends TargetImpl { - + protected final FilterInPlay additionalFilter; protected final Target originalTarget; protected static final Integer minNumberOfTargets = null; protected static final Integer maxNumberOfTargets = null; protected static final Zone zone = null; - public TargetWithAdditionalFilter(final TargetWithAdditionalFilter target){ - this(target.originalTarget, target.additionalFilter, false); + public TargetWithAdditionalFilter(final TargetWithAdditionalFilter target) { + this(target.originalTarget, target.additionalFilter, false); } - public TargetWithAdditionalFilter(Target originalTarget, FilterInPlay additionalFilter){ + public TargetWithAdditionalFilter(Target originalTarget, FilterInPlay additionalFilter) { this(originalTarget, additionalFilter, false); } - public TargetWithAdditionalFilter(Target originalTarget, FilterInPlay additionalFilter, boolean notTarget){ + public TargetWithAdditionalFilter(Target originalTarget, FilterInPlay additionalFilter, boolean notTarget) { originalTarget = originalTarget.copy(); originalTarget.clearChosen(); this.originalTarget = originalTarget; @@ -283,7 +279,7 @@ class TargetWithAdditionalFilter extends TargetImpl { public int getMaxNumberOfTargets() { return originalTarget.getMaxNumberOfTargets(); } - + @Override public void setMinNumberOfTargets(int minNumberOfTargets) { originalTarget.setMinNumberOfTargets(minNumberOfTargets); @@ -305,57 +301,53 @@ class TargetWithAdditionalFilter extends TargetImpl { if (obj == null) { obj = game.getPlayer(id); } - + try { return obj != null - && originalTarget.canTarget(id, game) - && additionalFilter.match((T) obj, game); + && originalTarget.canTarget(id, game) + && additionalFilter.match((T) obj, game); } catch (ClassCastException e) { return false; } } - @Override public boolean canTarget(UUID id, Ability source, Game game) { MageItem obj = game.getObject(id); if (obj == null) { obj = game.getPlayer(id); } - + try { return obj != null - && originalTarget.canTarget(id, source, game) - && additionalFilter.match((T) obj, source.getSourceId(), source.getControllerId(), game); + && originalTarget.canTarget(id, source, game) + && additionalFilter.match((T) obj, source.getSourceId(), source.getControllerId(), game); } catch (ClassCastException e) { return false; } } - @Override public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { MageItem obj = game.getObject(id); if (obj == null) { obj = game.getPlayer(id); } - + try { return obj != null - && originalTarget.canTarget(controllerId, id, source, game) - && additionalFilter.match((T) obj, source.getSourceId(), controllerId, game); + && originalTarget.canTarget(controllerId, id, source, game) + && additionalFilter.match((T) obj, source.getSourceId(), controllerId, game); } catch (ClassCastException e) { return false; } } - @Override public FilterInPlay getFilter() { return new CompoundFilter((FilterInPlay) originalTarget.getFilter(), additionalFilter, originalTarget.getFilter().getMessage()); } - @Override public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { int remainingTargets = getNumberOfTargets() - targets.size(); @@ -371,19 +363,19 @@ class TargetWithAdditionalFilter extends TargetImpl { } try { if (!targets.containsKey(objId) - && obj != null - && additionalFilter.match((T) obj, sourceId, sourceControllerId, game)) { + && obj != null + && additionalFilter.match((T) obj, sourceId, sourceControllerId, game)) { count++; if (count >= remainingTargets) { return true; } } - } catch (ClassCastException e) {} + } catch (ClassCastException e) { + } } return false; } - @Override public boolean canChoose(UUID sourceControllerId, Game game) { int remainingTargets = getNumberOfTargets() - targets.size(); @@ -399,19 +391,19 @@ class TargetWithAdditionalFilter extends TargetImpl { } try { if (!targets.containsKey(objId) - && obj != null - && additionalFilter.match((T) obj, game)) { + && obj != null + && additionalFilter.match((T) obj, game)) { count++; if (count >= remainingTargets) { return true; } } - } catch (ClassCastException e) {} + } catch (ClassCastException e) { + } } return false; } - @Override public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { Set ret = new HashSet<>(); @@ -422,15 +414,15 @@ class TargetWithAdditionalFilter extends TargetImpl { } try { if (obj != null - && additionalFilter.match((T) obj, sourceId, sourceControllerId, game)) { + && additionalFilter.match((T) obj, sourceId, sourceControllerId, game)) { ret.add(id); } - } catch (ClassCastException e) {} + } catch (ClassCastException e) { + } } return ret; } - @Override public Set possibleTargets(UUID sourceControllerId, Game game) { Set ret = new HashSet<>(); @@ -441,15 +433,15 @@ class TargetWithAdditionalFilter extends TargetImpl { } try { if (obj != null - && additionalFilter.match((T) obj, game)) { + && additionalFilter.match((T) obj, game)) { ret.add(id); } - } catch (ClassCastException e) {} + } catch (ClassCastException e) { + } } return ret; } - @Override public TargetWithAdditionalFilter copy() { return new TargetWithAdditionalFilter(this); @@ -458,7 +450,7 @@ class TargetWithAdditionalFilter extends TargetImpl { @Override public String getTargetedName(Game game) { StringBuilder sb = new StringBuilder(); - for (UUID targetId: getTargets()) { + for (UUID targetId : getTargets()) { MageObject object = game.getObject(targetId); if (object != null) { sb.append(object.getLogName()).append(" "); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java index fcec4c594c6..f2cfb84dccc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java @@ -57,9 +57,7 @@ public class CopyTargetSpellEffect extends OneShotEffect { spell = (Spell) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.STACK); } if (spell != null) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId());; game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); Player player = game.getPlayer(source.getControllerId()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/EpicEffect.java b/Mage/src/main/java/mage/abilities/effects/common/EpicEffect.java index 0b6b895c50b..00c8f1c17c5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/EpicEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/EpicEffect.java @@ -51,9 +51,7 @@ public class EpicEffect extends OneShotEffect { if (controller != null) { StackObject stackObject = game.getStack().getStackObject(source.getId()); Spell spell = (Spell) stackObject; - spell = spell.copySpell(); - spell.setCopiedSpell(true); - spell.setControllerId(source.getControllerId()); + spell = spell.copySpell(source.getControllerId()); // Remove Epic effect from the spell Effect epicEffect = null; for (Effect effect : spell.getSpellAbility().getEffects()) { diff --git a/Mage/src/main/java/mage/abilities/keyword/ConspireAbility.java b/Mage/src/main/java/mage/abilities/keyword/ConspireAbility.java index a1321b9e9bc..745063af04a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ConspireAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ConspireAbility.java @@ -292,9 +292,7 @@ class ConspireEffect extends OneShotEffect { if (controller != null && conspiredSpell != null) { Card card = game.getCard(conspiredSpell.getSourceId()); if (card != null) { - Spell copy = conspiredSpell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = conspiredSpell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); if (!game.isSimulation()) { diff --git a/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java b/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java index 109a7d02318..e95f1c7225e 100644 --- a/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.abilities.keyword; import mage.MageObjectReference; @@ -42,8 +41,6 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.watchers.common.GravestormWatcher; - - /** * * @author emerald000 @@ -57,6 +54,7 @@ public class GravestormAbility extends TriggeredAbilityImpl { private GravestormAbility(final GravestormAbility ability) { super(ability); } + @Override public GravestormAbility copy() { return new GravestormAbility(this); @@ -84,7 +82,7 @@ public class GravestormAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Gravestorm (When you cast this spell, copy it for each permanent put into a graveyard this turn. You may choose new targets for the copies.)" ; + return "Gravestorm (When you cast this spell, copy it for each permanent put into a graveyard this turn. You may choose new targets for the copies.)"; } } @@ -111,9 +109,7 @@ class GravestormEffect extends OneShotEffect { game.informPlayers("Gravestorm: " + spell.getName() + " will be copied " + gravestormCount + " time" + (gravestormCount > 1 ? "s" : "")); } for (int i = 0; i < gravestormCount; i++) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); } diff --git a/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java index 752bcd6c7bd..8cc53faa197 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java @@ -247,9 +247,7 @@ class ReplicateCopyEffect extends OneShotEffect { } // create the copies for (int i = 0; i < replicateCount; i++) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); if (!game.isSimulation()) { diff --git a/Mage/src/main/java/mage/abilities/keyword/StormAbility.java b/Mage/src/main/java/mage/abilities/keyword/StormAbility.java index 9994e218b05..5c54c47d401 100644 --- a/Mage/src/main/java/mage/abilities/keyword/StormAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/StormAbility.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.abilities.keyword; import mage.MageObjectReference; @@ -42,8 +41,6 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.watchers.common.CastSpellLastTurnWatcher; - - /** * * @author Plopman @@ -57,6 +54,7 @@ public class StormAbility extends TriggeredAbilityImpl { private StormAbility(final StormAbility ability) { super(ability); } + @Override public StormAbility copy() { return new StormAbility(this); @@ -84,7 +82,7 @@ public class StormAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Storm (When you cast this spell, copy it for each spell cast before it this turn. You may choose new targets for the copies.)" ; + return "Storm (When you cast this spell, copy it for each spell cast before it this turn. You may choose new targets for the copies.)"; } } @@ -108,12 +106,10 @@ class StormEffect extends OneShotEffect { Spell spell = (Spell) this.getValue("StormSpell"); if (spell != null) { if (!game.isSimulation()) { - game.informPlayers("Storm: " + spell.getLogName() + " will be copied " + stormCount + " time" + (stormCount > 1 ?"s":"")); + game.informPlayers("Storm: " + spell.getLogName() + " will be copied " + stormCount + " time" + (stormCount > 1 ? "s" : "")); } for (int i = 0; i < stormCount; i++) { - Spell copy = spell.copySpell(); - copy.setControllerId(source.getControllerId()); - copy.setCopiedSpell(true); + Spell copy = spell.copySpell(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); } diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index 0c14adfa3de..9a2eb2609c3 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -139,10 +139,8 @@ public class Spell extends StackObjImpl implements Card { payNoMana |= spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE); if (ignoreAbility) { ignoreAbility = false; - } else { - if (!spellAbility.activate(game, payNoMana)) { - return false; - } + } else if (!spellAbility.activate(game, payNoMana)) { + return false; } } return true; @@ -630,9 +628,21 @@ public class Spell extends StackObjImpl implements Card { return new Spell(this); } - public Spell copySpell() { - // replaced card.copy by copy (card content should no longer be changed) - return new Spell(this.card, this.ability.copySpell(), this.controllerId, this.fromZone); + public Spell copySpell(UUID newController) { + Spell copy = new Spell(this.card, this.ability.copySpell(), this.controllerId, this.fromZone); + boolean firstDone = false; + for (SpellAbility spellAbility : this.getSpellAbilities()) { + if (!firstDone) { + firstDone = true; + continue; + } + SpellAbility newAbility = spellAbility.copy(); // e.g. spliced spell + newAbility.newId(); + copy.addSpellAbility(newAbility); + } + copy.setCopy(true); + copy.setControllerId(newController); + return copy; } @Override