* 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).

This commit is contained in:
LevelX2 2020-07-14 21:30:30 +02:00
parent eecaa232f5
commit bd9738f128
5 changed files with 69 additions and 30 deletions

View file

@ -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());

View file

@ -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());
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);
//enchantAbility.setTargetName(target.getTargetName());
if (enchantedCreature != null) {
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;
}
}

View file

@ -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);
}

View file

@ -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 {
}
}

View file

@ -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));
}