Fix a number of problems with copying permanents.

Copying between face-down permanents, flip cards and transform cards wasn't always working as described in rule 706. This should fix most of those problems.
This commit is contained in:
elcnesh
2014-06-14 22:29:14 +00:00
parent ac6a2965f7
commit 8efc6bda85
7 changed files with 234 additions and 239 deletions

View File

@@ -288,7 +288,7 @@ public class Match {
if (!lostOwnership.isEmpty()) {
List<PaperCard> lostPaperOwnership = new ArrayList<>();
for(Card c : lostOwnership) {
lostPaperOwnership.add(c.getPaperCard());
lostPaperOwnership.add((PaperCard)c.getPaperCard());
}
if (outcome.anteResult.containsKey(fromGame)) {
outcome.anteResult.get(fromGame).addLost(lostPaperOwnership);
@@ -300,7 +300,7 @@ public class Match {
if (!gainedOwnership.isEmpty()) {
List<PaperCard> gainedPaperOwnership = new ArrayList<>();
for(Card c : gainedOwnership) {
gainedPaperOwnership.add(c.getPaperCard());
gainedPaperOwnership.add((PaperCard)c.getPaperCard());
}
if (outcome.anteResult.containsKey(fromGame)) {
outcome.anteResult.get(fromGame).addWon(gainedPaperOwnership);

View File

@@ -6,6 +6,7 @@ import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardCharacteristics;
import forge.game.card.CardFactory;
import forge.game.card.CardFactoryUtil;
import forge.game.card.CardUtil;
@@ -105,8 +106,7 @@ public class CloneEffect extends SpellAbilityEffect {
tgtCard.addAlternateState(CardCharacteristicName.Cloner);
tgtCard.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloner);
tgtCard.setState(CardCharacteristicName.Original);
}
else {
} else {
//copy Original state to Cloned
tgtCard.addAlternateState(CardCharacteristicName.Cloned);
tgtCard.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloned);
@@ -114,51 +114,34 @@ public class CloneEffect extends SpellAbilityEffect {
tgtCard.setState(CardCharacteristicName.Original);
}
}
CardCharacteristicName stateToCopy = null;
final CardCharacteristicName origState = cardToCopy.getCurState();
if (copyingSelf) {
stateToCopy = CardCharacteristicName.Cloned;
cardToCopy.setState(CardCharacteristicName.Cloned);
}
else if (cardToCopy.isFlipCard()) {
stateToCopy = CardCharacteristicName.Original;
}
else {
stateToCopy = cardToCopy.getCurState();
CardFactory.copyCopiableCharacteristics(cardToCopy, tgtCard);
if (copyingSelf) {
cardToCopy.setState(origState);
}
CardFactory.copyState(cardToCopy, stateToCopy, tgtCard);
// must call this before addAbilityFactoryAbilities so cloned added abilities are handled correctly
addExtraCharacteristics(tgtCard, sa, origSVars);
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
for (int i = 0; i < tgtCard.getStaticAbilityStrings().size(); i++) {
tgtCard.addStaticAbility(tgtCard.getStaticAbilityStrings().get(i));
}
CardFactory.copyCopiableAbilities(cardToCopy, tgtCard);
// restore name if it should be unchanged
if (keepName) {
tgtCard.setName(originalName);
tgtCard.setName(originalName);
}
// If target is a flipped card, also copy the flipped
// If target is a flip card, also set characteristics of the flipped
// state.
if (cardToCopy.isFlipCard()) {
if (!copyingSelf) {
tgtCard.addAlternateState(CardCharacteristicName.Flipped);
tgtCard.setState(CardCharacteristicName.Flipped);
}
CardFactory.copyState(cardToCopy, CardCharacteristicName.Flipped, tgtCard);
addExtraCharacteristics(tgtCard, sa, origSVars);
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
for (int i = 0; i < tgtCard.getStaticAbilityStrings().size(); i++) {
tgtCard.addStaticAbility(tgtCard.getStaticAbilityStrings().get(i));
}
final CardCharacteristics flippedState = tgtCard.getState(CardCharacteristicName.Flipped);
if (keepName) {
tgtCard.setName(originalName);
flippedState.setName(originalName);
}
//keep the Clone card image for the cloned card
tgtCard.setImageKey(imageFileName);
if (tgtCard.getCurState() != CardCharacteristicName.Flipped) {
tgtCard.setState(CardCharacteristicName.Original);
}
flippedState.setImageKey(imageFileName);
}
//Clean up copy of cloned state
@@ -263,7 +246,7 @@ public class CloneEffect extends SpellAbilityEffect {
}
}
// set power of clone
// set ETB tapped of clone
if (sa.hasParam("IntoPlayTapped")) {
tgtCard.setTapped(true);
}

View File

@@ -6,7 +6,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.StaticData;
import forge.card.CardCharacteristicName;
import forge.card.CardRulesPredicates;
import forge.game.Game;
import forge.game.GameEntity;
@@ -15,7 +14,6 @@ import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardFactory;
import forge.game.card.CardFactoryUtil;
import forge.game.card.CardLists;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
@@ -148,102 +146,13 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
for (final Card c : tgtCards) {
if ((tgt == null) || c.canBeTargetedBy(sa)) {
boolean wasInAlt = false;
CardCharacteristicName stateName = CardCharacteristicName.Original;
if (c.isInAlternateState()) {
stateName = c.getCurState();
wasInAlt = true;
c.setState(CardCharacteristicName.Original);
}
// start copied Kiki code
int multiplier = numCopies * hostCard.getController().getTokenDoublersMagnitude();
final List<Card> crds = new ArrayList<Card>(multiplier);
for (int i = 0; i < multiplier; i++) {
// TODO Use central copy methods
Card copy;
if (!c.isToken() || c.isCopiedToken()) {
// copy creature and put it onto the battlefield
copy = CardFactory.getCard(c.getPaperCard(), sa.getActivatingPlayer());
copy.setToken(true);
copy.setCopiedToken(true);
} else { // isToken()
copy = CardFactory.copyStats(c, controller);
copy.setName(c.getName());
copy.setImageKey(c.getImageKey());
copy.setManaCost(c.getManaCost());
copy.setColor(c.getColor());
copy.setToken(true);
copy.setType(c.getType());
copy.setBaseAttack(c.getBaseAttack());
copy.setBaseDefense(c.getBaseDefense());
CardFactoryUtil.addAbilityFactoryAbilities(copy);
for (String s : copy.getStaticAbilityStrings()) {
copy.addStaticAbility(s);
}
}
// when copying something stolen:
copy.setController(controller, 0);
copy.setCurSetCode(c.getCurSetCode());
if (c.isDoubleFaced()) { // Cloned DFC's can't transform
if (wasInAlt) {
copy.setState(CardCharacteristicName.Transformed);
}
}
if (c.isFlipCard()) { // Cloned Flips CAN flip.
copy.setState(CardCharacteristicName.Original);
c.setState(CardCharacteristicName.Original);
copy.setImageKey(c.getImageKey());
if (!c.isInAlternateState()) {
copy.setState(CardCharacteristicName.Flipped);
}
c.setState(CardCharacteristicName.Flipped);
}
if (c.isFaceDown()) {
c.setState(CardCharacteristicName.FaceDown);
}
if (sa.hasParam("AttachedTo")) {
List<Card> list = AbilityUtils.getDefinedCards(hostCard,
sa.getParam("AttachedTo"), sa);
if (list.isEmpty()) {
list = copy.getController().getGame().getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copy.getController(), copy);
}
if (!list.isEmpty()) {
Card attachedTo = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(list, sa, copy + " - Select a card to attach to.");
if (copy.isAura()) {
if (attachedTo.canBeEnchantedBy(copy)) {
copy.enchantEntity(attachedTo);
} else {//can't enchant
continue;
}
} else if (copy.isEquipment()) { //Equipment
if (attachedTo.canBeEquippedBy(copy)) {
copy.equipCard(attachedTo);
} else {
continue;
}
} else { // Fortification
copy.fortifyCard(attachedTo);
}
} else {
continue;
}
}
final Card copy = CardFactory.copyCopiableCharacteristics(c, sa.getActivatingPlayer());
copy.setToken(true);
copy.setCopiedToken(true);
// add keywords from sa
for (final String kw : keywords) {
copy.addIntrinsicKeyword(kw);
@@ -260,20 +169,55 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, copy, false);
copy.addTrigger(parsedTrigger);
}
copy = game.getAction().moveToPlay(copy);
CardFactory.copyCopiableAbilities(c, copy);
copy.setCloneOrigin(hostCard);
sa.getHostCard().addClone(copy);
crds.add(copy);
final Card copyInPlay = game.getAction().moveToPlay(copy);
// when copying something stolen:
copyInPlay.setController(controller, 0);
copyInPlay.setCurSetCode(c.getCurSetCode());
copyInPlay.setCloneOrigin(hostCard);
sa.getHostCard().addClone(copyInPlay);
crds.add(copyInPlay);
if (sa.hasParam("RememberCopied")) {
hostCard.addRemembered(copy);
hostCard.addRemembered(copyInPlay);
}
if (sa.hasParam("Tapped")) {
copy.setTapped(true);
copyInPlay.setTapped(true);
}
if (sa.hasParam("CopyAttacking") && game.getPhaseHandler().inCombat()) {
final GameEntity defender = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("CopyAttacking"), sa).get(0);
game.getCombat().addAttacker(copy, defender);
game.getCombat().addAttacker(copyInPlay, defender);
}
if (sa.hasParam("AttachedTo")) {
List<Card> list = AbilityUtils.getDefinedCards(hostCard,
sa.getParam("AttachedTo"), sa);
if (list.isEmpty()) {
list = copyInPlay.getController().getGame().getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copyInPlay.getController(), copyInPlay);
}
if (!list.isEmpty()) {
Card attachedTo = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(list, sa, copyInPlay + " - Select a card to attach to.");
if (copyInPlay.isAura()) {
if (attachedTo.canBeEnchantedBy(copyInPlay)) {
copyInPlay.enchantEntity(attachedTo);
} else {//can't enchant
continue;
}
} else if (copyInPlay.isEquipment()) { //Equipment
if (attachedTo.canBeEquippedBy(copyInPlay)) {
copyInPlay.equipCard(attachedTo);
} else {
continue;
}
} else { // Fortification
copyInPlay.fortifyCard(attachedTo);
}
} else {
continue;
}
}
}
@@ -282,10 +226,6 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
final String location = sa.getParam("AtEOT");
registerDelayedTrigger(sa, location, crds);
}
if (wasInAlt) {
c.setState(stateName);
}
} // end canBeTargetedBy
} // end foreach Card
} // end resolve

View File

@@ -79,7 +79,7 @@ public class PlayLandVariantEffect extends SpellAbilityEffect {
source.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloner);
source.setState(CardCharacteristicName.Original);
CardCharacteristicName stateToCopy = random.getCurState();
CardFactory.copyState(random, stateToCopy, source);
CardFactory.copyState(random, stateToCopy, source, source.getCurState());
source.setImageKey(imageFileName);
source.setController(activator, 0);

View File

@@ -82,6 +82,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class Card extends GameEntity implements Comparable<Card> {
private final int uniqueNumber;
private final IPaperCard paperCard;
private final Map<CardCharacteristicName, CardCharacteristics> characteristicsMap
= new EnumMap<CardCharacteristicName, CardCharacteristics>(CardCharacteristicName.class);
@@ -242,10 +243,24 @@ public class Card extends GameEntity implements Comparable<Card> {
}
/**
* Instantiates a new card.
* Instantiates a new card not associated to any paper card.
* @param id the unique id of the new card.
*/
public Card(int id) {
public Card(final int id) {
this(id, null);
}
/**
* Instantiates a new card with a given paper card.
* @param id the unique id of the new card.
* @param paperCard the {@link IPaperCard} of which the new card is a
* representation, or {@code null} if this new {@link Card} doesn't represent any paper
* card.
* @see IPaperCard
*/
public Card(final int id, final IPaperCard paperCard) {
this.uniqueNumber = id;
this.paperCard = paperCard;
this.characteristicsMap.put(CardCharacteristicName.Original, new CardCharacteristics());
this.characteristicsMap.put(CardCharacteristicName.FaceDown, CardUtil.getFaceDownCharacteristic());
}
@@ -8911,15 +8926,20 @@ public class Card extends GameEntity implements Comparable<Card> {
return fromPaperCard(pc, null);
}
public PaperCard getPaperCard() {
public IPaperCard getPaperCard() {
IPaperCard cp = this.paperCard;
if (cp != null) {
return cp;
}
final String name = getName();
final String set = getCurSetCode();
if (StringUtils.isNotBlank(set)) {
PaperCard cp = StaticData.instance().getVariantCards().getCard(name, set);
cp = StaticData.instance().getVariantCards().getCard(name, set);
return cp == null ? StaticData.instance().getCommonCards().getCard(name, set) : cp;
}
PaperCard cp = StaticData.instance().getVariantCards().getCard(name);
cp = StaticData.instance().getVariantCards().getCard(name);
return cp == null ? StaticData.instance().getCommonCards().getCardFromEdition(name, SetPreference.Latest) : cp;
}

View File

@@ -71,27 +71,13 @@ public class CardFactory {
* @return a {@link forge.game.card.Card} object.
*/
public final static Card copyCard(final Card in, boolean assignNewId) {
final CardCharacteristicName curState = in.getCurState();
boolean alternate = false;
if (in.isInAlternateState()) {
alternate = true;
in.setState(CardCharacteristicName.Original);
}
Card out = null;
Card out;
if (!in.isToken() || in.isCopiedToken()) {
out = assignNewId ? getCard(in.getPaperCard(), in.getOwner())
: getCard(in.getPaperCard(), in.getOwner(), in.getUniqueNumber());
} else { // token
out = assignNewId ? new Card(in.getGame().nextCardId()) : new Card(in.getUniqueNumber());
out = assignNewId ? new Card(in.getGame().nextCardId(), in.getPaperCard()) : new Card(in.getUniqueNumber(), in.getPaperCard());
out = CardFactory.copyStats(in, in.getController());
out.setName(in.getName());
out.setImageKey(in.getImageKey());
out.setManaCost(in.getManaCost());
out.setColor(in.getColor());
out.setType(in.getType());
out.setBaseAttack(in.getBaseAttack());
out.setBaseDefense(in.getBaseDefense());
out.setToken(true);
CardFactoryUtil.addAbilityFactoryAbilities(out);
@@ -99,22 +85,11 @@ public class CardFactory {
out.addStaticAbility(s);
}
}
CardFactory.copyCharacteristics(in, out);
if (in.hasAlternateState()) {
for (final CardCharacteristicName state : in.getStates()) {
in.setState(state);
if (state == CardCharacteristicName.Cloner) {
out.addAlternateState(state);
}
out.setState(state);
CardFactory.copyCharacteristics(in, out);
}
for (final CardCharacteristicName state : in.getStates()) {
CardFactory.copyState(in, state, out, state);
}
if (alternate) {
in.setState(curState);
}
out.setState(curState);
out.setState(in.getCurState());
// I'm not sure if we really should be copying enchant/equip stuff over.
out.setEquipping(in.getEquipping());
@@ -254,7 +229,7 @@ public class CardFactory {
public final static Card getCard(final IPaperCard cp, final Player owner, final int cardId) {
//System.out.println(cardName);
CardRules cardRules = cp.getRules();
final Card c = readCard(cardRules, cardId);
final Card c = readCard(cardRules, cp, cardId);
c.setRules(cardRules);
c.setOwner(owner);
buildAbilities(c);
@@ -383,9 +358,9 @@ public class CardFactory {
card.setSVar("DamagePWY", "Count$YourLifeTotal");
}
private static Card readCard(final CardRules rules, int cardId) {
private static Card readCard(final CardRules rules, final IPaperCard paperCard, int cardId) {
final Card card = new Card(cardId);
final Card card = new Card(cardId, paperCard);
// 1. The states we may have:
CardSplitType st = rules.getSplitType();
@@ -466,81 +441,128 @@ public class CardFactory {
c.setBaseDefenseString(face.getToughness());
}
}
/**
* Create a copy of a card, including its copiable characteristics (but not
* abilities).
* @param from
* @param newOwner
* @return
*/
public static Card copyCopiableCharacteristics(final Card from, final Player newOwner) {
int id = newOwner == null ? 0 : newOwner.getGame().nextCardId();
final Card c = new Card(id, from.getPaperCard());
c.setOwner(newOwner);
c.setCurSetCode(from.getCurSetCode());
copyCopiableCharacteristics(from, c);
return c;
}
/**
* Copy the copiable characteristics of one card to another, taking the
* states of both cards into account.
*
* @param from the {@link Card} to copy from.
* @param to the {@link Card} to copy to.
*/
public static void copyCopiableCharacteristics(final Card from, final Card to) {
final boolean toIsFaceDown = to.isFaceDown();
if (toIsFaceDown) {
// If to is face down, copy to its front side
to.setState(CardCharacteristicName.Original);
copyCopiableCharacteristics(from, to);
to.setState(CardCharacteristicName.FaceDown);
return;
}
final boolean fromIsFlipCard = from.isFlipCard();
if (fromIsFlipCard) {
if (to.getCurState().equals(CardCharacteristicName.Flipped)) {
copyState(from, CardCharacteristicName.Original, to, CardCharacteristicName.Original);
} else {
copyState(from, CardCharacteristicName.Original, to, to.getCurState());
}
copyState(from, CardCharacteristicName.Flipped, to, CardCharacteristicName.Flipped);
} else {
copyState(from, from.getCurState(), to, to.getCurState());
}
}
/**
* Copy the copiable abilities of one card to another, taking the states of
* both cards into account.
*
* @param from the {@link Card} to copy from.
* @param to the {@link Card} to copy to.
*/
public static void copyCopiableAbilities(final Card from, final Card to) {
final boolean toIsFaceDown = to.isFaceDown();
if (toIsFaceDown) {
// If to is face down, copy to its front side
to.setState(CardCharacteristicName.Original);
copyCopiableAbilities(from, to);
to.setState(CardCharacteristicName.FaceDown);
return;
}
final boolean fromIsFlipCard = from.isFlipCard();
if (fromIsFlipCard) {
copyAbilities(from, CardCharacteristicName.Original, to, to.getCurState());
copyAbilities(from, CardCharacteristicName.Flipped, to, CardCharacteristicName.Flipped);
} else {
copyAbilities(from, from.getCurState(), to, to.getCurState());
}
}
/**
* <p>
* Copies stats like power, toughness, etc.
* Copy stats like power, toughness, etc. from one card to another.
* </p>
* <p>
* The copy is made independently for each state of the input {@link Card}.
* This amounts to making a full copy of the card, including the current
* state.
* </p>
*
* @param sim
* a {@link java.lang.Object} object.
* @param in
* the {@link forge.game.card.Card} to be copied.
* @param newOwner
* @return a {@link forge.game.card.Card} object.
* the {@link forge.game.player.Player} to be the owner of the newly
* created Card.
* @return a new {@link forge.game.card.Card}.
*/
public static Card copyStats(final Card sim, Player newOwner) {
public static Card copyStats(final Card in, final Player newOwner) {
int id = newOwner == null ? 0 : newOwner.getGame().nextCardId();
final Card c = new Card(id);
final Card c = new Card(id, in.getPaperCard());
c.setOwner(newOwner);
c.setCurSetCode(sim.getCurSetCode());
c.setCurSetCode(in.getCurSetCode());
final CardCharacteristicName origState = sim.getCurState();
for (final CardCharacteristicName state : sim.getStates()) {
c.addAlternateState(state);
c.setState(state);
sim.setState(state);
CardFactory.copyCharacteristics(sim, c);
for (final CardCharacteristicName state : in.getStates()) {
CardFactory.copyState(in, state, c, state);
}
sim.setState(origState);
c.setState(origState);
c.setRules(sim.getRules());
c.setState(in.getCurState());
c.setRules(in.getRules());
return c;
} // copyStats()
/**
* Copy characteristics.
* Copy characteristics of a particular state of one card to those of a
* (possibly different) state of another.
*
* @param from
* the from
* the {@link Card} to copy from.
* @param fromState
* the {@link CardCharacteristicName} of {@code from} to copy from.
* @param to
* the to
* the {@link Card} to copy to.
* @param toState
* the {@link CardCharacteristicName} of {@code to} to copy to.
*/
private static void copyCharacteristics(final Card from, final Card to) {
to.setBaseAttack(from.getBaseAttack());
to.setBaseDefense(from.getBaseDefense());
to.setBaseLoyalty(from.getBaseLoyalty());
to.setBaseAttackString(from.getBaseAttackString());
to.setBaseDefenseString(from.getBaseDefenseString());
to.setIntrinsicKeyword(from.getIntrinsicKeyword());
to.setName(from.getName());
to.setType(from.getCharacteristics().getType());
to.setText(from.getSpellText());
to.setManaCost(from.getManaCost());
to.setColor(from.getColor());
to.setSVars(from.getSVars());
to.setIntrinsicAbilities(from.getUnparsedAbilities());
to.setImageKey(from.getImageKey());
to.setTriggers(from.getTriggers(), true);
to.setReplacementEffects(from.getReplacementEffects());
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
}
/**
* Copy characteristics.
*
* @param from
* the from
* @param stateToCopy
* the state to copy
* @param to
* the to
*/
public static void copyState(final Card from, final CardCharacteristicName stateToCopy, final Card to) {
public static void copyState(final Card from, final CardCharacteristicName fromState, final Card to, final CardCharacteristicName toState) {
// copy characteristics not associated with a state
to.setBaseLoyalty(from.getBaseLoyalty());
to.setBaseAttackString(from.getBaseAttackString());
@@ -548,11 +570,41 @@ public class CardFactory {
to.setText(from.getSpellText());
// get CardCharacteristics for desired state
CardCharacteristics characteristics = from.getState(stateToCopy);
to.getCharacteristics().copyFrom(characteristics);
if (!to.getStates().contains(toState)) {
to.addAlternateState(toState);
}
final CardCharacteristics toCharacteristics = to.getState(toState),
fromCharacteristics = from.getState(fromState);
toCharacteristics.copyFrom(fromCharacteristics);
}
/**
* Copy the abilities (including static abilities, triggers, and replacement
* effects) from one card to another.
*
* @param from the {@link Card} to copy from.
* @param fromState the {@link CardCharacteristicName} of {@code from} to copy from.
* @param to the {@link Card} to copy to.
* @param toState the {@link CardCharacteristicName} of {@code to} to copy to.
*/
private static void copyAbilities(final Card from, final CardCharacteristicName fromState, final Card to, final CardCharacteristicName toState) {
final CardCharacteristics fromCharacteristics = from.getState(fromState);
final CardCharacteristicName oldToState = to.getCurState();
if (!to.getStates().contains(toState)) {
to.addAlternateState(toState);
}
to.setState(toState);
// handle triggers and replacement effect through Card class interface
to.setTriggers(characteristics.getTriggers(), true);
to.setReplacementEffects(characteristics.getReplacementEffects());
to.setTriggers(fromCharacteristics.getTriggers(), true);
to.setReplacementEffects(fromCharacteristics.getReplacementEffects());
// add abilities
CardFactoryUtil.addAbilityFactoryAbilities(to);
for (String staticAbility : to.getStaticAbilityStrings()) {
to.addStaticAbility(staticAbility);
}
// reset state
to.setState(oldToState);
}
public static void copySpellAbility(SpellAbility from, SpellAbility to) {

View File

@@ -139,7 +139,7 @@ public final class CardUtil {
*/
public static Card getLKICopy(final Card in) {
final Card newCopy = new Card(in.getUniqueNumber());
final Card newCopy = new Card(in.getUniqueNumber(), in.getPaperCard());
newCopy.setCurSetCode(in.getCurSetCode());
newCopy.setOwner(in.getOwner());
newCopy.setController(in.getController(), 0);