From 2ef5f67fb83f4b3e25d15d81a8a92d1055f3010f Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Tue, 12 Apr 2022 22:24:48 +0200 Subject: [PATCH 1/6] 707.10: Copied spells incomplete --- .../src/main/java/forge/game/card/Card.java | 13 ++++------ .../java/forge/game/card/CardFactory.java | 2 ++ .../java/forge/game/card/CardProperty.java | 26 +++++++++---------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4298b73bf16..d64b0a5b3af 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1258,14 +1258,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final int getXManaCostPaid() { - SpellAbility castSA; - if (getCopiedPermanent() != null) { - castSA = getCopiedPermanent().getCastSA(); - } else { - castSA = getCastSA(); - } - if (castSA != null) { - Integer paid = castSA.getXManaCostPaid(); + if (getCastSAFallBack() != null) { + Integer paid = getCastSAFallBack().getXManaCostPaid(); return paid == null ? 0 : paid; } return 0; @@ -6092,6 +6086,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public SpellAbility getCastSA() { return castSA; } + public SpellAbility getCastSAFallBack() { + return getCopiedPermanent() != null ? getCopiedPermanent().getCastSA() : castSA; + } public void setCastSA(SpellAbility castSA) { this.castSA = castSA; diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 2a9b6e232bf..829a0196eb7 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -124,6 +124,8 @@ public class CardFactory { final Game game = source.getGame(); final Card c = new Card(game.nextCardId(), original.getPaperCard(), game); copyCopiableCharacteristics(original, c); + // fix old cardstates + buildAbilities(c); if (sourceSA.hasParam("NonLegendary")) { c.removeType(CardType.Supertype.Legendary); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 0e5c27ffb0e..76ffee1567e 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1680,40 +1680,40 @@ public class CardProperty { if (!card.isOptionalCostPaid(OptionalCost.Generic)) return false; } } else if (property.equals("surged")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isSurged(); + return card.getCastSAFallBack().isSurged(); } else if (property.equals("blitzed")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } return card.getCastSA().isBlitz(); } else if (property.equals("dashed")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isDash(); + return card.getCastSAFallBack().isDash(); } else if (property.equals("escaped")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isEscape(); + return card.getCastSAFallBack().isEscape(); } else if (property.equals("evoked")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isEvoke(); + return card.getCastSAFallBack().isEvoke(); } else if (property.equals("prowled")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isProwl(); + return card.getCastSAFallBack().isProwl(); } else if (property.equals("spectacle")) { - if (card.getCastSA() == null) { + if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isSpectacle(); + return card.getCastSAFallBack().isSpectacle(); } else if (property.equals("foretold")) { if (!card.isForetold()) { return false; From e782ec07c76b56a695ffe61e8c0dbc3764503e92 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Tue, 12 Apr 2022 22:32:07 +0200 Subject: [PATCH 2/6] Clean up --- forge-game/src/main/java/forge/game/card/CardFactory.java | 2 -- forge-game/src/main/java/forge/game/card/CardProperty.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 829a0196eb7..2a9b6e232bf 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -124,8 +124,6 @@ public class CardFactory { final Game game = source.getGame(); final Card c = new Card(game.nextCardId(), original.getPaperCard(), game); copyCopiableCharacteristics(original, c); - // fix old cardstates - buildAbilities(c); if (sourceSA.hasParam("NonLegendary")) { c.removeType(CardType.Supertype.Legendary); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 76ffee1567e..59dc0bdedc4 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1688,7 +1688,7 @@ public class CardProperty { if (card.getCastSAFallBack() == null) { return false; } - return card.getCastSA().isBlitz(); + return card.getCastSAFallBack().isBlitz(); } else if (property.equals("dashed")) { if (card.getCastSAFallBack() == null) { return false; From 16613fe1d01767d70bd1ed198802ff23b0fc241b Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Apr 2022 11:46:12 +0200 Subject: [PATCH 3/6] set castSA on copy --- .../src/main/java/forge/game/GameAction.java | 2 +- .../src/main/java/forge/game/card/Card.java | 7 ++--- .../java/forge/game/card/CardFactory.java | 5 ++-- .../java/forge/game/card/CardProperty.java | 28 +++++++++---------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index a69075a3342..85adc237c6a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -815,7 +815,7 @@ public class GameAction { } else { c.setCastFrom(zoneFrom); } - if (cause != null && cause.isSpell() && c.equals(cause.getHostCard()) && !c.isCopiedSpell()) { + if (cause != null && cause.isSpell() && c.equals(cause.getHostCard())) { c.setCastSA(cause); } else { c.setCastSA(null); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index d64b0a5b3af..1452ab0f760 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1258,8 +1258,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final int getXManaCostPaid() { - if (getCastSAFallBack() != null) { - Integer paid = getCastSAFallBack().getXManaCostPaid(); + if (getCastSA() != null) { + Integer paid = getCastSA().getXManaCostPaid(); return paid == null ? 0 : paid; } return 0; @@ -6086,9 +6086,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public SpellAbility getCastSA() { return castSA; } - public SpellAbility getCastSAFallBack() { - return getCopiedPermanent() != null ? getCopiedPermanent().getCastSA() : castSA; - } public void setCastSA(SpellAbility castSA) { this.castSA = castSA; diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 2a9b6e232bf..3cf97aedde0 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -163,6 +163,8 @@ public class CardFactory { c.setCopiedSpell(true); c.setCopiedPermanent(original); + c.setCastSA(targetSA); + c.setXManaCostPaidByColor(original.getXManaCostPaidByColor()); c.setKickerMagnitude(original.getKickerMagnitude()); @@ -792,9 +794,6 @@ public class CardFactory { state.setImageKey(ImageKeys.getTokenKey("eternalize_" + name + "_" + set)); } - // set the host card for copied replacement effects - // needed for copied xPaid ETB effects (for the copy, xPaid = 0) - if (sa.hasParam("GainTextOf") && originalState != null) { state.setSetCode(originalState.getSetCode()); state.setRarity(originalState.getRarity()); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 59dc0bdedc4..0e5c27ffb0e 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1680,40 +1680,40 @@ public class CardProperty { if (!card.isOptionalCostPaid(OptionalCost.Generic)) return false; } } else if (property.equals("surged")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isSurged(); + return card.getCastSA().isSurged(); } else if (property.equals("blitzed")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isBlitz(); + return card.getCastSA().isBlitz(); } else if (property.equals("dashed")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isDash(); + return card.getCastSA().isDash(); } else if (property.equals("escaped")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isEscape(); + return card.getCastSA().isEscape(); } else if (property.equals("evoked")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isEvoke(); + return card.getCastSA().isEvoke(); } else if (property.equals("prowled")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isProwl(); + return card.getCastSA().isProwl(); } else if (property.equals("spectacle")) { - if (card.getCastSAFallBack() == null) { + if (card.getCastSA() == null) { return false; } - return card.getCastSAFallBack().isSpectacle(); + return card.getCastSA().isSpectacle(); } else if (property.equals("foretold")) { if (!card.isForetold()) { return false; From 12774df9295e9b379b6f044bea459c0801ee5fa1 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Apr 2022 12:57:06 +0200 Subject: [PATCH 4/6] Fix 107.3j --- .../java/forge/game/ability/AbilityUtils.java | 18 ++++++++---------- .../main/java/forge/game/card/CardFactory.java | 4 +++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 5766f20cc25..74e37ceb437 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1715,6 +1715,12 @@ public class AbilityUtils { return doXMath(root.getXManaCostPaid(), expr, c, ctb); } + // If the chosen creature has X in its mana cost, that X is considered to be 0. + // The value of X in Altered Ego’s last ability will be whatever value was chosen for X while casting Altered Ego. + if (sa.isCopiedTrait() && !sa.getHostCard().equals(c)) { + return doXMath(0, expr, c, ctb); + } + if (root.isTrigger()) { Trigger t = root.getTrigger(); if (t == null) { @@ -1755,16 +1761,8 @@ public class AbilityUtils { } } - // If the chosen creature has X in its mana cost, that X is considered to be 0. - // The value of X in Altered Ego’s last ability will be whatever value was chosen for X while casting Altered Ego. - if (sa.isCopiedTrait() || !sa.getHostCard().equals(c)) { - return doXMath(0, expr, c, ctb); - } - - if (root.isReplacementAbility()) { - if (sa.hasParam("ETB")) { - return doXMath(c.getXManaCostPaid(), expr, c, ctb); - } + if (root.isReplacementAbility() && sa.hasParam("ETB")) { + return doXMath(c.getXManaCostPaid(), expr, c, ctb); } return doXMath(0, expr, c, ctb); diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 3cf97aedde0..8fcc987388a 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -174,8 +174,10 @@ public class CardFactory { if (targetSA.isBestow()) { c.animateBestow(); } + return c; } + /** *

* copySpellAbilityAndPossiblyHost. @@ -306,7 +308,7 @@ public class CardFactory { buildPlaneAbilities(card); } CardFactoryUtil.setupKeywordedAbilities(card); // Should happen AFTER setting left/right split abilities to set Fuse ability to both sides - card.getView().updateState(card); + card.updateStateForView(); } private static void buildPlaneAbilities(Card card) { From 41843ddf28a3e95fd23ffbe19f3bcb31efcff7a2 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Apr 2022 14:46:59 +0200 Subject: [PATCH 5/6] Fix 707.10b --- forge-game/src/main/java/forge/game/card/CardFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 8fcc987388a..66bb3d4673a 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -207,6 +207,8 @@ public class CardFactory { } copySA.setCopied(true); + // 707.10b + copySA.setOriginalAbility(targetSA); if (targetSA.usesTargeting()) { // do for SubAbilities too? From 234484bbfc8aa0b1d247b2bfafe69770cfff91bf Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Apr 2022 20:04:59 +0200 Subject: [PATCH 6/6] Mana isn't an object that can be copied --- forge-game/src/main/java/forge/game/GameAction.java | 2 +- forge-game/src/main/java/forge/game/card/CardFactory.java | 3 +-- forge-game/src/main/java/forge/game/player/Player.java | 1 - .../src/main/java/forge/game/spellability/SpellAbility.java | 6 +++++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 85adc237c6a..ecf8f2f12fb 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -403,7 +403,7 @@ public class GameAction { if (copied.isAura() && !copied.isAttachedToEntity() && toBattlefield) { if (zoneFrom != null && zoneFrom.is(ZoneType.Stack) && game.getStack().isResolving(c)) { boolean found = false; - if (Iterables.any(game.getPlayers(),PlayerPredicates.canBeAttached(copied))) { + if (Iterables.any(game.getPlayers(), PlayerPredicates.canBeAttached(copied))) { found = true; } if (Iterables.any((CardCollectionView) params.get(AbilityKey.LastStateBattlefield), CardPredicates.canBeAttached(copied))) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 66bb3d4673a..178a1ef7543 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -163,8 +163,6 @@ public class CardFactory { c.setCopiedSpell(true); c.setCopiedPermanent(original); - c.setCastSA(targetSA); - c.setXManaCostPaidByColor(original.getXManaCostPaidByColor()); c.setKickerMagnitude(original.getKickerMagnitude()); @@ -209,6 +207,7 @@ public class CardFactory { copySA.setCopied(true); // 707.10b copySA.setOriginalAbility(targetSA); + c.setCastSA(copySA); if (targetSA.usesTargeting()) { // do for SubAbilities too? diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 975a5ad7b0a..40219ef3089 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -3396,7 +3396,6 @@ public class Player extends GameEntity implements Comparable { equippedThisTurn = 0; } - public boolean hasUrzaLands() { final CardCollectionView landsControlled = getCardsIn(ZoneType.Battlefield); return Iterables.any(landsControlled, Predicates.and(CardPredicates.isType("Urza's"), CardPredicates.isType("Mine"))) diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 4740745cfa4..a255568c5ed 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -1115,7 +1115,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit clone.changeZoneTable = new CardZoneTable(changeZoneTable); } - clone.payingMana = Lists.newArrayList(payingMana); + clone.payingMana = Lists.newArrayList(); + // mana is not copied + if (lki) { + clone.payingMana.addAll(payingMana); + } clone.paidAbilities = Lists.newArrayList(); clone.setPaidHash(Maps.newHashMap(getPaidHash()));