mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user