From 639277402d46f77ff039451cd5b449ef108c22b7 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Sat, 17 Sep 2022 09:27:49 -0400 Subject: [PATCH] Fix #8485 --- .../main/java/mage/abilities/AbilityImpl.java | 28 +++++++++--------- .../abilities/effects/ContinuousEffects.java | 9 ------ .../keyword/SpliceOntoArcaneAbility.java | 9 ++++-- .../SpliceOntoInstantOrSorceryAbility.java | 8 ++++- Mage/src/main/java/mage/util/CardUtil.java | 29 ++++++++----------- 5 files changed, 40 insertions(+), 43 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index d27577ed0e..bfc5fe7434 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -253,14 +253,6 @@ public abstract class AbilityImpl implements Ability { } setSourcePermanentTransformCount(game); - /* 20130201 - 601.2b - * If the player wishes to splice any cards onto the spell (see rule 702.45), he - * or she reveals those cards in their hand. - */ - if (this.abilityType == AbilityType.SPELL) { - game.getContinuousEffects().applySpliceEffects(this, game); - } - // if ability can be cast for no mana, clear the mana costs now, because additional mana costs must be paid. // For Flashback ability can be set X before, so the X costs have to be restored for the flashbacked ability if (noMana) { @@ -277,12 +269,24 @@ public abstract class AbilityImpl implements Ability { } } + // fused or spliced spells contain multiple abilities (e.g. fused, left, right) + // optional costs and cost modification must be applied only to the first/main ability + boolean isMainPartAbility = !CardUtil.isFusedPartAbility(this, game); + + /* 20220908 - 601.2b + * If the player wishes to splice any cards onto the spell (see rule 702.45), they + * reveal those cards in their hand. + */ + if (isMainPartAbility && this.abilityType == AbilityType.SPELL) { + game.getContinuousEffects().applySpliceEffects(this, game); + } + // 20130201 - 601.2b // If the spell has alternative or additional costs that will be paid as it's being cast such // as buyback, kicker, or convoke costs (see rules 117.8 and 117.9), the player announces his // or her intentions to pay any or all of those costs (see rule 601.2e). // A player can't apply two alternative methods of casting or two alternative costs to a single spell. - if (!activateAlternateOrAdditionalCosts(sourceObject, noMana, controller, game)) { + if (isMainPartAbility && !activateAlternateOrAdditionalCosts(sourceObject, noMana, controller, game)) { if (getAbilityType() == AbilityType.SPELL && ((SpellAbility) this).getSpellAbilityType() == SpellAbilityType.FACE_DOWN_CREATURE) { return false; @@ -385,12 +389,8 @@ public abstract class AbilityImpl implements Ability { return false; } - // fused spell contains 3 abilities (fused, left, right) - // fused cost added to fused ability, so no need cost modification for other parts - boolean needCostModification = !CardUtil.isFusedPartAbility(this, game); - //20101001 - 601.2e - if (needCostModification) { + if (isMainPartAbility) { adjustCosts(game); // still needed for CostAdjuster objects (to handle some types of dynamic costs) game.getContinuousEffects().costModification(this, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index 31bd0688ec..9111b4d161 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -765,15 +765,6 @@ public class ContinuousEffects implements Serializable { public void applySpliceEffects(Ability abilityToModify, Game game) { // add effects from splice card to spell ability on activate/cast - // splice spell - spell can't be spliced again - if (CardUtil.isSpliceAbility(abilityToModify, game)) { - return; - } - // fused spell - can be spliced only to main fused ability, not to parts - if (CardUtil.isFusedPartAbility(abilityToModify, game)) { - return; - } - List spliceEffects = getApplicableSpliceCardEffects(game, abilityToModify.getControllerId()); // get the applyable splice abilities List spliceAbilities = new ArrayList<>(); diff --git a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java index c6a604730c..9e95938301 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import java.util.Iterator; @@ -9,6 +8,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.SpliceCardEffectImpl; import mage.cards.Card; @@ -147,7 +147,12 @@ class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { splicedAbility.setSourceId(abilityToModify.getSourceId()); spell.addSpellAbility(splicedAbility); for (Iterator it = ((SpliceOntoArcaneAbility) source).getSpliceCosts().iterator(); it.hasNext();) { - spell.getSpellAbility().getCosts().add(((Cost) it.next()).copy()); + Cost cost = (Cost) it.next(); + if (cost instanceof ManaCost) { + spell.getSpellAbility().getManaCostsToPay().add((ManaCost) cost.copy()); + } else { + spell.getSpellAbility().getCosts().add(cost.copy()); + } } } return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java index ce87c33251..7afa8e282d 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java @@ -7,6 +7,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.SpliceCardEffectImpl; import mage.cards.Card; @@ -150,7 +151,12 @@ class SpliceOntoInstantOrSorceryEffect extends SpliceCardEffectImpl { splicedAbility.setSourceId(abilityToModify.getSourceId()); spell.addSpellAbility(splicedAbility); for (Iterator it = ((SpliceOntoInstantOrSorceryAbility) source).getSpliceCosts().iterator(); it.hasNext(); ) { - spell.getSpellAbility().getCosts().add(((Cost) it.next()).copy()); + Cost cost = (Cost) it.next(); + if (cost instanceof ManaCost) { + spell.getSpellAbility().getManaCostsToPay().add((ManaCost) cost.copy()); + } else { + spell.getSpellAbility().getCosts().add(cost.copy()); + } } } return true; diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 6eb78df91e..8a3c8ea295 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -911,26 +911,21 @@ public final class CardUtil { return Outcome.BoostCreature; } - public static boolean isSpliceAbility(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - return ((SpellAbility) ability).getSpellAbilityType() == SpellAbilityType.SPLICE; - } - return false; - } - public static boolean isFusedPartAbility(Ability ability, Game game) { // TODO: does it work fine with copies of spells on stack? - if (ability instanceof SpellAbility) { - Spell mainSpell = game.getSpell(ability.getId()); - if (mainSpell == null) { - return true; - } else { - SpellAbility mainSpellAbility = mainSpell.getSpellAbility(); - return mainSpellAbility.getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED - && !ability.equals(mainSpellAbility); - } + if (!(ability instanceof SpellAbility)) { + return false; } - return false; + if (((SpellAbility) ability).getSpellAbilityType() == SpellAbilityType.SPLICE) { + return true; + } + Spell mainSpell = game.getSpell(ability.getId()); + if (mainSpell == null) { + return true; + } + SpellAbility mainSpellAbility = mainSpell.getSpellAbility(); + return mainSpellAbility.getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED + && !ability.equals(mainSpellAbility); } public static Abilities getAbilities(MageObject object, Game game) {