From e389b95738c74ee95d567cbdd75b1324b844d0f8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 14 Nov 2018 05:02:29 +0400 Subject: [PATCH] * Fixed exception error on copy of copy of aura effects for some cards (Estrid's masks, Animate Dead, etc); * Fixed wrong copy effects on rollbacks or errors; --- .../effects/common/CopyPermanentEffect.java | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java index d74258916f..c8aeb347db 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java @@ -1,12 +1,12 @@ package mage.abilities.effects.common; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EnchantAbility; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; @@ -20,8 +20,9 @@ import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; import mage.util.functions.EmptyApplyToPermanent; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class CopyPermanentEffect extends OneShotEffect { @@ -59,7 +60,9 @@ public class CopyPermanentEffect extends OneShotEffect { super(effect); this.filter = effect.filter.copy(); this.applier = effect.applier; - this.bluePrintPermanent = effect.bluePrintPermanent; + if (effect.bluePrintPermanent != null) { + this.bluePrintPermanent = effect.bluePrintPermanent.copy(); + } this.useTargetOfAbility = effect.useTargetOfAbility; } @@ -84,42 +87,70 @@ public class CopyPermanentEffect extends OneShotEffect { } if (copyFromPermanent != null) { bluePrintPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, applier); - - //if object is a copy of an aura, it needs to attach - if (bluePrintPermanent.hasSubtype(SubType.AURA, game)){ + if (bluePrintPermanent == null) { + return false; + } + + // if object is a copy of an aura, it needs to attach again for new target + if (bluePrintPermanent.hasSubtype(SubType.AURA, game)) { //copied from mage.cards.c.CopyEnchantment.java - Target target = bluePrintPermanent.getSpellAbility().getTargets().get(0); + + // permanent can be attached (Estrid's Mask) or enchant (Utopia Sprawl) + // TODO: fix Animate Dead -- it's can't be copied (can't retarget) Outcome auraOutcome = Outcome.BoostCreature; + Target auraTarget = null; + + // attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it) for (Ability ability : bluePrintPermanent.getAbilities()) { if (ability instanceof SpellAbility) { for (Effect effect : ability.getEffects()) { if (effect instanceof AttachEffect) { - auraOutcome = effect.getOutcome(); + if (bluePrintPermanent.getSpellAbility().getTargets().size() > 0) { + auraTarget = bluePrintPermanent.getSpellAbility().getTargets().get(0); + auraOutcome = effect.getOutcome(); + } } } } } - - /*if this is a copy of a copy, the copy's target has been - *copied and needs to be cleared - */ - { - UUID targetId = target.getFirstTarget(); - if(targetId != null) - target.remove(targetId); + + // enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it) + if (auraTarget == null) { + for (Ability ability : bluePrintPermanent.getAbilities()) { + if (ability instanceof EnchantAbility) { + if (ability.getTargets().size() > 0) { // Animate Dead don't have targets + auraTarget = ability.getTargets().get(0); + for (Effect effect : ability.getEffects()) { + // first outcome + auraOutcome = effect.getOutcome(); + } + } + } + } } - - target.setNotTarget(true); - if (controller.choose(auraOutcome, target, source.getSourceId(), game)) { - UUID targetId = target.getFirstTarget(); - Permanent targetPermanent = game.getPermanent(targetId); - Player targetPlayer = game.getPlayer(targetId); - if (targetPermanent != null) { - targetPermanent.addAttachment(sourcePermanent.getId(), game); - } else if (targetPlayer != null) { - targetPlayer.addAttachment(sourcePermanent.getId(), game); - } else { - return false; + + /* if this is a copy of a copy, the copy's target has been + * copied and needs to be cleared + */ + if (auraTarget != null) { + // clear selected target + if (auraTarget.getFirstTarget() != null) { + auraTarget.remove(auraTarget.getFirstTarget()); + } + + // select new target + auraTarget.setNotTarget(true); + if (controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) { + UUID targetId = auraTarget.getFirstTarget(); + Permanent targetPermanent = game.getPermanent(targetId); + Player targetPlayer = game.getPlayer(targetId); + if (targetPermanent != null) { + targetPermanent.addAttachment(sourcePermanent.getId(), game); + } else if (targetPlayer != null) { + targetPlayer.addAttachment(sourcePermanent.getId(), game); + } else { + return false; + } } } }