Fix DFC copy having both faces

This commit is contained in:
Bug Hunter
2022-02-16 12:04:44 +00:00
committed by Hans Mackowiak
parent 39c49b2315
commit cbf1bdd3a5
19 changed files with 46 additions and 73 deletions

View File

@@ -756,9 +756,9 @@ public class AiController {
}
// state needs to be switched here so API checks evaluate the right face
CardStateName currentState = sa.getCardState() != null && sa.getHostCard().getCurrentStateName() != sa.getCardState().getStateName() && !sa.getHostCard().isInPlay() ? sa.getHostCard().getCurrentStateName() : null;
CardStateName currentState = sa.getCardState() != null && sa.getHostCard().getCurrentStateName() != sa.getCardStateName() && !sa.getHostCard().isInPlay() ? sa.getHostCard().getCurrentStateName() : null;
if (currentState != null) {
sa.getHostCard().setState(sa.getCardState().getStateName(), false);
sa.getHostCard().setState(sa.getCardStateName(), false);
}
AiPlayDecision canPlay = canPlaySa(sa); // this is the "heaviest" check, which also sets up targets, defines X, etc.

View File

@@ -299,7 +299,7 @@ public class ControlGainAi extends SpellAbilityAi {
final Game game = ai.getGame();
// Special card logic that is processed elsewhere
if (sa.getParam("AILogic").equals("DonateTargetPerm")) {
if (("DonateTargetPerm").equals(sa.getParam("AILogic"))) {
// Donate step 2 - target a donatable permanent.
return SpecialCardAi.Donate.considerDonatingPermanent(ai, sa);
}

View File

@@ -186,7 +186,7 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
artIndex = Math.max(artIndex0, IPaperCard.DEFAULT_ART_INDEX);
foil = foil0;
rarity = rarity0;
artist = (artist0 != null ? TextUtil.normalizeText(artist0) : IPaperCard.NO_ARTIST_NAME);
artist = artist0 != null ? TextUtil.normalizeText(artist0) : IPaperCard.NO_ARTIST_NAME;
collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER;
// If the user changes the language this will make cards sort by the old language until they restart the game.
// This is a good tradeoff

View File

@@ -1601,15 +1601,11 @@ public class AbilityUtils {
if (sa.hasParam("ForgetOtherTargets")) {
host.clearRemembered();
}
for (final GameObject o : sa.getTargets()) {
host.addRemembered(o);
}
host.addRemembered(sa.getTargets());
}
if (sa.hasParam("ImprintTargets") && sa.usesTargeting()) {
for (final Card c : sa.getTargets().getTargetCards()) {
host.addImprintedCard(c);
}
host.addImprintedCards(sa.getTargets().getTargetCards());
}
if (sa.hasParam("RememberCostMana")) {

View File

@@ -142,9 +142,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
}
host.setChosenCards(chosen);
if (sa.hasParam("RememberChosen")) {
for (final Card rem : chosen) {
host.addRemembered(rem);
}
host.addRemembered(chosen);
}
}
}

View File

@@ -168,9 +168,7 @@ public class DigEffect extends SpellAbilityEffect {
if (!toReveal.isEmpty()) {
game.getAction().reveal(toReveal, cont);
if (sa.hasParam("RememberRevealed")) {
for (final Card one : toReveal) {
host.addRemembered(one);
}
host.addRemembered(toReveal);
}
}
}
@@ -329,7 +327,7 @@ public class DigEffect extends SpellAbilityEffect {
}
List<Card> chosen = new ArrayList<>();
int max = anyNumber ? valid.size() : Math.min(valid.size(),destZone1ChangeNum);
int max = anyNumber ? valid.size() : Math.min(valid.size(), destZone1ChangeNum);
int min = (anyNumber || optional) ? 0 : max;
if (max > 0) { // if max is 0 don't make a choice
chosen = chooser.getController().chooseEntitiesForEffect(valid, min, max, delayedReveal, sa, prompt, p, null);

View File

@@ -29,10 +29,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
String desc = "Card";
if (sa.hasParam("ValidDescription")) {
desc = sa.getParam("ValidDescription");
}
String desc = sa.getParamOrDefault("ValidDescription", "Card");
int untilAmount = 1;
if (sa.hasParam("Amount")) {
@@ -57,7 +54,6 @@ public class DigUntilEffect extends SpellAbilityEffect {
final ZoneType found = ZoneType.smartValueOf(sa.getParam("FoundDestination"));
final ZoneType revealed = ZoneType.smartValueOf(sa.getParam("RevealedDestination"));
if (found != null) {
sb.append(untilAmount > 1 ? "those cards" : "that card");
sb.append(" ");

View File

@@ -198,9 +198,7 @@ public class EffectEffect extends SpellAbilityEffect {
// Set Remembered
if (rememberList != null) {
for (final Object o : rememberList) {
eff.addRemembered(o);
}
eff.addRemembered(rememberList);
if (sa.hasParam("ForgetOnMoved")) {
addForgetOnMovedTrigger(eff, sa.getParam("ForgetOnMoved"));
if (!"Stack".equals(sa.getParam("ForgetOnMoved"))) {
@@ -219,9 +217,7 @@ public class EffectEffect extends SpellAbilityEffect {
// Set Imprinted
if (effectImprinted != null) {
for (final Card c : AbilityUtils.getDefinedCards(hostCard, effectImprinted, sa)) {
eff.addImprintedCard(c);
}
eff.addImprintedCards(AbilityUtils.getDefinedCards(hostCard, effectImprinted, sa));
}
// Note counters on defined

View File

@@ -79,9 +79,7 @@ public class FlipOntoBattlefieldEffect extends SpellAbilityEffect {
}
// Remember whatever was hit
for (Card c : hit) {
host.addRemembered(c);
}
host.addRemembered(hit);
}
@Override

View File

@@ -92,9 +92,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
if (randomChosen) {
for (Entry<Player, List<CardCollectionView>> ev : record.entrySet()) {
CardCollectionView chosen = Aggregates.random(ev.getValue());
for (Card c : chosen) {
source.addRemembered(c);
}
source.addRemembered(chosen);
}
SpellAbility sub = sa.getAdditionalAbility("ChosenPile");

View File

@@ -193,13 +193,9 @@ public class SubgameEffect extends SpellAbilityEffect {
if (sa.hasParam("RememberPlayers")) {
final String param = sa.getParam("RememberPlayers");
if (param.equals("Win")) {
for (Player p : winPlayers) {
hostCard.addRemembered(p);
}
hostCard.addRemembered(winPlayers);
} else if (param.equals("NotWin")) {
for (Player p : notWinPlayers) {
hostCard.addRemembered(p);
}
hostCard.addRemembered(notWinPlayers);
}
}

View File

@@ -117,9 +117,7 @@ public class VoteEffect extends SpellAbilityEffect {
if (sa.hasParam("Tied") && mostVotes.size() > 1) {
subAbs.add(sa.getParam("Tied"));
} else if (sa.hasParam("VoteSubAbility")) {
for (final Object o : mostVotes) {
host.addRemembered(o);
}
host.addRemembered(mostVotes);
subAbs.add(sa.getParam("VoteSubAbility"));
} else {
for (Object type : mostVotes) {

View File

@@ -784,13 +784,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return false;
}
CardStateName destState = transformCard.backside ? CardStateName.Original : CardStateName.Transformed;
// below only when in play
if (!isInPlay()) {
return true;
}
CardStateName destState = transformCard.backside ? CardStateName.Original : CardStateName.Transformed;
// use Original State for the transform check
if (!transformCard.getOriginalState(destState).getType().isPermanent()) {
return false;
@@ -887,7 +887,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final boolean hasAlternateState() {
// Note: Since FaceDown state is created lazily (whereas previously
// it was always created), adjust threshold based on its existence.
int threshold = (states.containsKey(CardStateName.FaceDown) ? 2 : 1);
int threshold = states.containsKey(CardStateName.FaceDown) ? 2 : 1;
int numStates = states.keySet().size();
@@ -6451,6 +6451,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return c.getCardForUi();
}
//allow special cards to override this function to return another card for the sake of UI logic
public Card getCardForUi() {
return this;
}
public IPaperCard getPaperCard() {
IPaperCard cp = paperCard;
if (cp != null) {
@@ -6486,11 +6491,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
staticCommandList.add(objects);
}
//allow special cards to override this function to return another card for the sake of UI logic
public Card getCardForUi() {
return this;
}
public String getOracleText() {
CardRules rules = cardRules;
if (copiedPermanent != null) { //return oracle text of copied permanent if applicable

View File

@@ -96,12 +96,8 @@ public class CardFactory {
out.setAttachedCards(in.getAttachedCards());
out.setEntityAttachedTo(in.getEntityAttachedTo());
for (final Object o : in.getRemembered()) {
out.addRemembered(o);
}
for (final Card o : in.getImprintedCards()) {
out.addImprintedCard(o);
}
out.addRemembered(in.getRemembered());
out.addImprintedCards(in.getImprintedCards());
out.setCommander(in.isRealCommander());
//out.setFaceDown(in.isFaceDown());
@@ -125,11 +121,9 @@ public class CardFactory {
private final static Card copySpellHost(final SpellAbility sourceSA, final SpellAbility targetSA, Player controller) {
final Card source = sourceSA.getHostCard();
final Card original = targetSA.getHostCard();
final Card c = copyCard(original, true);
// clear remember/imprint for copied spells
c.clearRemembered();
c.clearImprintedCards();
final Game game = source.getGame();
final Card c = new Card(game.nextCardId(), original.getPaperCard(), game);
copyCopiableCharacteristics(original, c);
if (sourceSA.hasParam("NonLegendary")) {
c.removeType(CardType.Supertype.Legendary);
@@ -524,8 +518,6 @@ public class CardFactory {
public static void copyState(final Card from, final CardStateName fromState, final Card to,
final CardStateName toState, boolean updateView) {
// copy characteristics not associated with a state
to.setBasePowerString(from.getBasePowerString());
to.setBaseToughnessString(from.getBaseToughnessString());
to.setText(from.getSpellText());
// get CardCharacteristics for desired state
@@ -753,7 +745,7 @@ public class CardFactory {
if (sa.hasParam("GainThisAbility") && (sa instanceof SpellAbility)) {
SpellAbility root = ((SpellAbility) sa).getRootAbility();
if (root.isTrigger() && root.getTrigger() != null) {
if (root.isTrigger()) {
state.addTrigger(root.getTrigger().copy(out, false));
} else if (root.isReplacementAbility()) {
state.addReplacementEffect(root.getReplacementEffect().copy(out, false));

View File

@@ -173,8 +173,7 @@ public abstract class CostPartWithList extends CostPart {
}
// copy table because the original get cleaned after the cost is done
final CardZoneTable copyTable = new CardZoneTable();
copyTable.putAll(table);
final CardZoneTable copyTable = new CardZoneTable(table);
copyTable.triggerChangesZoneAll(payer.getGame(), ability);
}

View File

@@ -195,8 +195,7 @@ public class CostPutCounter extends CostPartWithList {
return;
}
GameEntityCounterTable tempTable = new GameEntityCounterTable();
tempTable.putAll(counterTable);
GameEntityCounterTable tempTable = new GameEntityCounterTable(counterTable);
tempTable.replaceCounterEffect(ability.getHostCard().getGame(), ability, effect);
}

View File

@@ -19,6 +19,8 @@ package forge.game.spellability;
import java.util.Map;
import forge.card.CardStateName;
import forge.game.IHasSVars;
import forge.game.ability.AbilityFactory;
import forge.game.ability.ApiType;
import forge.game.ability.SpellAbilityEffect;
@@ -103,6 +105,14 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab
effect.resolve(this);
}
@Override
protected IHasSVars getSVarFallback() {
if (getCardState() != null && getCardStateName().equals(CardStateName.RightSplit)) {
return getCardState();
}
return super.getSVarFallback();
}
/** {@inheritDoc} */
@Override
public final Object clone() {

View File

@@ -174,11 +174,11 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
}
source.turnFaceDownNoUpdate();
lkicheck = true;
} else if (getCardState() != null && source.getCurrentStateName() != getCardStateName()) {
} else if (getCardState() != null && source.getCurrentStateName() != getCardStateName() && getHostCard().getState(getCardStateName()) != null) {
if (!source.isLKI()) {
source = CardUtil.getLKICopy(source);
}
CardStateName stateName = getCardState().getStateName();
CardStateName stateName = getCardStateName();
if (!source.hasState(stateName)) {
source.addAlternateState(stateName, false);
source.getState(stateName).copyFrom(getHostCard().getState(stateName), true);

View File

@@ -1104,8 +1104,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
clone.counterTable = new GameEntityCounterTable(counterTable);
}
if (changeZoneTable != null) {
clone.changeZoneTable = new CardZoneTable();
clone.changeZoneTable.putAll(changeZoneTable);
clone.changeZoneTable = new CardZoneTable(changeZoneTable);
}
clone.payingMana = Lists.newArrayList(payingMana);