From bd9738f128561e0a6c5dd443c93037724e39f104 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 14 Jul 2020 21:30:30 +0200 Subject: [PATCH] * Fixed a problem where for copies of cards/permanent the included spell ability was not correctly copied and the copied card had the spell ability twice. That could cause in some rare cases problems with spell ids of copies (this fixes #6824) or did allow on the other side some unproper handling of things (Animate Dead). --- .../src/main/java/mage/view/CardView.java | 18 +++--- Mage.Sets/src/mage/cards/a/AnimateDead.java | 63 +++++++++++++++---- .../src/mage/cards/d/DragonlordAtarka.java | 8 ++- .../src/mage/cards/g/GodEternalKefnet.java | 8 +-- Mage.Sets/src/mage/cards/l/LightningBolt.java | 2 +- 5 files changed, 69 insertions(+), 30 deletions(-) diff --git a/Mage.Common/src/main/java/mage/view/CardView.java b/Mage.Common/src/main/java/mage/view/CardView.java index 4b71867d57..15dabfd8c1 100644 --- a/Mage.Common/src/main/java/mage/view/CardView.java +++ b/Mage.Common/src/main/java/mage/view/CardView.java @@ -212,8 +212,8 @@ public class CardView extends SimpleCardView { * @param card * @param game * @param controlled is the card view created for the card controller - used - * for morph / face down cards to know which player may see information for - * the card + * for morph / face down cards to know which player may + * see information for the card */ public CardView(Card card, Game game, boolean controlled) { this(card, game, controlled, false, false); @@ -239,12 +239,14 @@ public class CardView extends SimpleCardView { /** * @param card * @param game - * @param controlled is the card view created for the card controller - used - * for morph / face down cards to know which player may see information for - * the card + * @param controlled is the card view created for the card controller + * - used for morph / face down cards to know which + * player may see information for the card * @param showFaceDownCard if true and the card is not on the battlefield, - * also a face down card is shown in the view, face down cards will be shown - * @param storeZone if true the card zone will be set in the zone attribute. + * also a face down card is shown in the view, face + * down cards will be shown + * @param storeZone if true the card zone will be set in the zone + * attribute. */ public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) { super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor()); @@ -334,7 +336,7 @@ public class CardView extends SimpleCardView { this.manaCostRight = splitCard.getRightHalfCard().getManaCost().getSymbols(); } else if (card instanceof AdventureCard) { AdventureCard adventureCard = ((AdventureCard) card); - AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard()); + AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard()); fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName(); this.manaCostLeft = adventureCardSpell.getManaCost().getSymbols(); this.manaCostRight = adventureCard.getManaCost().getSymbols(); diff --git a/Mage.Sets/src/mage/cards/a/AnimateDead.java b/Mage.Sets/src/mage/cards/a/AnimateDead.java index 4a2f98ff4f..cab559a1e4 100644 --- a/Mage.Sets/src/mage/cards/a/AnimateDead.java +++ b/Mage.Sets/src/mage/cards/a/AnimateDead.java @@ -1,4 +1,3 @@ - package mage.cards.a; import java.util.UUID; @@ -9,6 +8,7 @@ import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.SourceOnBattlefieldCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; @@ -27,6 +27,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -89,27 +90,28 @@ class AnimateDeadReAttachEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent enchantment = game.getPermanent(source.getSourceId()); + Permanent animateDead = game.getPermanent(source.getSourceId()); - if (controller != null && enchantment != null) { - Card cardInGraveyard = game.getCard(enchantment.getAttachedTo()); + if (controller != null && animateDead != null) { + Card cardInGraveyard = game.getCard(animateDead.getAttachedTo()); if (cardInGraveyard == null) { return true; } - - // put card into play + // put card into play from Graveyard controller.moveCards(cardInGraveyard, Zone.BATTLEFIELD, source, game); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); - FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); - filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); - Target target = new TargetCreaturePermanent(filter); - //enchantAbility.setTargetName(target.getTargetName()); if (enchantedCreature != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); + filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); + Target target = new TargetCreaturePermanent(filter); target.addTarget(enchantedCreature.getId(), source, game); - enchantment.getSpellAbility().getTargets().clear(); - enchantment.getSpellAbility().getTargets().add(target); - enchantedCreature.addAttachment(enchantment.getId(), game); + animateDead.getSpellAbility().getTargets().clear(); + animateDead.getSpellAbility().getTargets().add(target); + enchantedCreature.addAttachment(animateDead.getId(), game); + ContinuousEffect effect = new AnimateDeadAttachToPermanentEffect(); + effect.setTargetPointer(new FixedTarget(enchantedCreature, game)); + game.addEffect(effect, source); } return true; } @@ -232,3 +234,38 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou return false; } } + +class AnimateDeadAttachToPermanentEffect extends ContinuousEffectImpl { + + public AnimateDeadAttachToPermanentEffect() { + super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral); + } + + public AnimateDeadAttachToPermanentEffect(final AnimateDeadAttachToPermanentEffect effect) { + super(effect); + } + + @Override + public AnimateDeadAttachToPermanentEffect copy() { + return new AnimateDeadAttachToPermanentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent animateDead = game.getPermanent(source.getSourceId()); + if (animateDead != null) { + // The target has to be changed to CreaturePermanent because the reset from card resets it to Card in Graveyard + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); + filter.add(new PermanentIdPredicate(getTargetPointer().getFirst(game, source))); + Target target = new TargetCreaturePermanent(filter); + target.addTarget(((FixedTarget) getTargetPointer()).getTarget(), source, game); + animateDead.getSpellAbility().getTargets().clear(); + animateDead.getSpellAbility().getTargets().add(target); + } + if (animateDead == null) { + discard(); + } + return true; + } + +} diff --git a/Mage.Sets/src/mage/cards/d/DragonlordAtarka.java b/Mage.Sets/src/mage/cards/d/DragonlordAtarka.java index 68e4876378..68e0371562 100644 --- a/Mage.Sets/src/mage/cards/d/DragonlordAtarka.java +++ b/Mage.Sets/src/mage/cards/d/DragonlordAtarka.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.UUID; @@ -30,7 +29,7 @@ public final class DragonlordAtarka extends CardImpl { } public DragonlordAtarka(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELDER); this.subtype.add(SubType.DRAGON); @@ -45,7 +44,10 @@ public final class DragonlordAtarka extends CardImpl { // When Dragonlord Atarka enters the battlefield, it deals 5 damage divided as you choose among any number of target creatures and/or planeswalkers your opponents control. Ability ability = new EntersBattlefieldTriggeredAbility(new DamageMultiEffect(5, "it"), false); - ability.addTarget(new TargetCreatureOrPlaneswalkerAmount(5, filter)); + TargetCreatureOrPlaneswalkerAmount target = new TargetCreatureOrPlaneswalkerAmount(5, filter); + target.setMinNumberOfTargets(1); + target.setMaxNumberOfTargets(5); + ability.addTarget(target); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java b/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java index 3aecf9aeb7..626c5868a0 100644 --- a/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java +++ b/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java @@ -1,5 +1,7 @@ package mage.cards.g; +import java.awt.*; +import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; @@ -20,9 +22,6 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.watchers.common.CardsAmountDrawnThisTurnWatcher; -import java.awt.*; -import java.util.UUID; - /** * @author JayDi85 */ @@ -94,7 +93,7 @@ class GodEternalKefnetDrawCardReplacementEffect extends ReplacementEffectImpl { // cast copy if (topCard.isInstantOrSorcery() && you.chooseUse(outcome, "Would you like to copy " + topCard.getName() - + " and cast it {2} less?", source, game)) { + + " and cast it for {2} less?", source, game)) { Card blueprint = topCard.copy(); blueprint.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(2))); Card copiedCard = game.copyCard(blueprint, source, source.getControllerId()); @@ -154,4 +153,3 @@ class GodEternalKefnetDrawCardReplacementEffect extends ReplacementEffectImpl { } } - diff --git a/Mage.Sets/src/mage/cards/l/LightningBolt.java b/Mage.Sets/src/mage/cards/l/LightningBolt.java index 3fff879e9e..59235d5862 100644 --- a/Mage.Sets/src/mage/cards/l/LightningBolt.java +++ b/Mage.Sets/src/mage/cards/l/LightningBolt.java @@ -1,4 +1,3 @@ - package mage.cards.l; import java.util.UUID; @@ -17,6 +16,7 @@ public final class LightningBolt extends CardImpl { public LightningBolt(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + // Lightning Bolt deals 3 damage to any target. this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addEffect(new DamageTargetEffect(3)); }