From 4ff887959dae42c31c4f39f89f98dd70b993957f Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Sun, 23 Feb 2014 14:12:53 +0000 Subject: [PATCH] fix incorrect mana bills for human (eg: ai plays Mana Leak, with Goblin Electromancer in play) --- .gitattributes | 2 +- .../main/java/forge/ai/ComputerUtilMana.java | 3 +- .../java/forge/ai/PlayerControllerAi.java | 4 +- .../java/forge/game/cost/CostPartMana.java | 2 +- .../ManaCostAdjustment.java} | 200 +++++++++++++++--- .../forge/game/mana/ManaCostBeingPaid.java | 132 +----------- .../forge/game/player/PlayerController.java | 6 +- .../game/staticability/StaticAbility.java | 33 --- .../main/java/forge/gui/player/HumanPlay.java | 16 +- .../gui/player/PlayerControllerHuman.java | 7 +- .../util/PlayerControllerForTests.java | 5 +- 11 files changed, 197 insertions(+), 213 deletions(-) rename forge-game/src/main/java/forge/game/{staticability/StaticAbilityCostChange.java => mana/ManaCostAdjustment.java} (58%) diff --git a/.gitattributes b/.gitattributes index 141534ad23a..4619f04077a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -491,6 +491,7 @@ forge-game/src/main/java/forge/game/event/GameEventZone.java -text forge-game/src/main/java/forge/game/event/IGameEventVisitor.java -text forge-game/src/main/java/forge/game/event/package-info.java -text forge-game/src/main/java/forge/game/mana/Mana.java svneol=native#text/plain +forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java -text forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java svneol=native#text/plain forge-game/src/main/java/forge/game/mana/ManaPool.java svneol=native#text/plain forge-game/src/main/java/forge/game/mana/package-info.java svneol=native#text/plain @@ -554,7 +555,6 @@ forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.j forge-game/src/main/java/forge/game/staticability/StaticAbilityCantBeCast.java svneol=native#text/plain forge-game/src/main/java/forge/game/staticability/StaticAbilityCantTarget.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java svneol=native#text/plain -forge-game/src/main/java/forge/game/staticability/StaticAbilityCostChange.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityETBTapped.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityPreventDamage.java svneol=native#text/plain diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 180473b6e18..273626b1ba7 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -19,6 +19,7 @@ import forge.game.cost.Cost; import forge.game.cost.CostPartMana; import forge.game.cost.CostPayment; import forge.game.mana.Mana; +import forge.game.mana.ManaCostAdjustment; import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaPool; import forge.game.player.Player; @@ -633,7 +634,7 @@ public class ComputerUtilMana { restriction = payCosts.getCostMana().getRestiction(); } ManaCostBeingPaid cost = new ManaCostBeingPaid(mana, restriction); - cost.applySpellCostChange(sa, test); + ManaCostAdjustment.adjust(cost, sa, test); final Card card = sa.getHostCard(); // Tack xMana Payments into mana here if X is a set value diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 5ff1a1b2d82..07560f91806 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -717,9 +717,9 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */ ) { + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa ) { // TODO Auto-generated method stub - ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, false, 0); + ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0) : new ManaCostBeingPaid(toPay); return ComputerUtilMana.payManaCost(cost, sa, player); } diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index 1c5427b1d1c..8a8664422aa 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -128,7 +128,7 @@ public class CostPartMana extends CostPart { sa.clearManaPaid(); // decision not used here, the whole payment is interactive! - return payer.getController().payManaCost(this, sa, null); + return payer.getController().payManaCost(this, sa, null, true); } } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCostChange.java b/forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java similarity index 58% rename from forge-game/src/main/java/forge/game/staticability/StaticAbilityCostChange.java rename to forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java index 2b91add4671..709463cea55 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCostChange.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java @@ -1,41 +1,182 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.game.staticability; +package forge.game.mana; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.common.collect.Lists; import forge.card.mana.ManaCostShard; +import forge.game.Game; import forge.game.card.Card; import forge.game.card.CardFactoryUtil; -import forge.game.mana.ManaCostBeingPaid; +import forge.game.card.CardLists; +import forge.game.card.CardPredicates; import forge.game.player.Player; import forge.game.spellability.AbilityActivated; import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; +import forge.game.staticability.StaticAbility; import forge.game.zone.ZoneType; -import java.util.List; -import java.util.Map; +public class ManaCostAdjustment { -/** - * The Class StaticAbility_CantBeCast. - */ -public class StaticAbilityCostChange { + public static final void adjust(ManaCostBeingPaid cost, final SpellAbility sa, boolean test) { + final Game game = sa.getActivatingPlayer().getGame(); + // Beached + final Card originalCard = sa.getHostCard(); + if (sa.isXCost() && !originalCard.isCopiedSpell()) { + originalCard.setXManaCostPaid(0); + } + + if (sa.isTrigger()) { + return; + } + + if (sa.isSpell()) { + if (sa.isDelve()) { + final Player pc = originalCard.getController(); + final List mutableGrave = new ArrayList(pc.getCardsIn(ZoneType.Graveyard)); + final List toExile = pc.getController().chooseCardsToDelve(cost.getColorlessManaAmount(), mutableGrave); + for (final Card c : toExile) { + cost.decreaseColorlessMana(1); + if (!test) { + pc.getGame().getAction().exile(c); + } + } + } + else if (sa.getHostCard().hasKeyword("Convoke")) { + adjustCostByConvoke(cost, sa); + } + } // isSpell + + List cardsOnBattlefield = Lists.newArrayList(game.getCardsIn(ZoneType.Battlefield)); + cardsOnBattlefield.addAll(game.getCardsIn(ZoneType.Stack)); + cardsOnBattlefield.addAll(game.getCardsIn(ZoneType.Command)); + if (!cardsOnBattlefield.contains(originalCard)) { + cardsOnBattlefield.add(originalCard); + } + final ArrayList raiseAbilities = new ArrayList(); + final ArrayList reduceAbilities = new ArrayList(); + final ArrayList setAbilities = new ArrayList(); + + // Sort abilities to apply them in proper order + for (Card c : cardsOnBattlefield) { + final ArrayList staticAbilities = c.getStaticAbilities(); + for (final StaticAbility stAb : staticAbilities) { + if (stAb.getMapParams().get("Mode").equals("RaiseCost")) { + raiseAbilities.add(stAb); + } + else if (stAb.getMapParams().get("Mode").equals("ReduceCost")) { + reduceAbilities.add(stAb); + } + else if (stAb.getMapParams().get("Mode").equals("SetCost")) { + setAbilities.add(stAb); + } + } + } + // Raise cost + for (final StaticAbility stAb : raiseAbilities) { + applyAbility(stAb, "RaiseCost", sa, cost); + } + + // Reduce cost + for (final StaticAbility stAb : reduceAbilities) { + applyAbility(stAb, "ReduceCost", sa, cost); + } + if (sa.isSpell() && sa.isOffering()) { // cost reduction from offerings + adjustCostByOffering(cost, sa); + } + + // Set cost (only used by Trinisphere) is applied last + for (final StaticAbility stAb : setAbilities) { + applyAbility(stAb, "SetCost", sa, cost); + } + } // GetSpellCostChange + + /** + * Apply ability. + * + * @param mode + * the mode + * @param sa + * the SpellAbility + * @param originalCost + * the originalCost + * @return the modified ManaCost + */ + private static final void applyAbility(StaticAbility stAb, final String mode, final SpellAbility sa, final ManaCostBeingPaid originalCost) { + + // don't apply the ability if it hasn't got the right mode + if (!stAb.getMapParams().get("Mode").equals(mode)) { + return; + } + + if (stAb.isSuppressed() || !stAb.checkConditions()) { + return; + } + + if (mode.equals("RaiseCost")) { + applyRaiseCostAbility(stAb, sa, originalCost); + } + if (mode.equals("ReduceCost")) { + applyReduceCostAbility(stAb, sa, originalCost); + } + if (mode.equals("SetCost")) { //Set cost is only used by Trinisphere + applyRaiseCostAbility(stAb, sa, originalCost); + } + } + + private static void adjustCostByConvoke(ManaCostBeingPaid cost, final SpellAbility sa) { + + List untappedCreats = CardLists.filter(sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); + untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED); + + Map convokedCards = sa.getActivatingPlayer().getController().chooseCardsForConvoke(sa, cost.toManaCost(), untappedCreats); + + // Convoked creats are tapped here with triggers suppressed, + // Then again when payment is done(In InputPayManaCost.done()) with suppression cleared. + // This is to make sure that triggers go off at the right time + // AND that you can't use mana tapabilities of convoked creatures to pay the convoked cost. + for (final Entry conv : convokedCards.entrySet()) { + sa.addTappedForConvoke(conv.getKey()); + cost.decreaseShard(conv.getValue(), 1); + conv.getKey().setTapped(true); + } + } + + private static void adjustCostByOffering(final ManaCostBeingPaid cost, final SpellAbility sa) { + String offeringType = ""; + for (String kw : sa.getHostCard().getKeyword()) { + if (kw.endsWith(" offering")) { + offeringType = kw.split(" ")[0]; + break; + } + } + + Card toSac = null; + List canOffer = CardLists.filter(sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), + CardPredicates.isType(offeringType)); + + final List toSacList = sa.getHostCard().getController().getController().choosePermanentsToSacrifice(sa, 0, 1, canOffer, + offeringType); + + if (!toSacList.isEmpty()) { + toSac = toSacList.get(0); + } + else { + return; + } + + cost.subtractManaCost(toSac.getManaCost()); + + sa.setSacrificedAsOffering(toSac); + toSac.setUsedToPay(true); //stop it from interfering with mana input + } + /** * Applies applyRaiseCostAbility ability. * @@ -46,7 +187,7 @@ public class StaticAbilityCostChange { * @param originalCost * a ManaCost */ - public static void applyRaiseCostAbility(final StaticAbility staticAbility, final SpellAbility sa, final ManaCostBeingPaid manaCost) { + private static void applyRaiseCostAbility(final StaticAbility staticAbility, final SpellAbility sa, final ManaCostBeingPaid manaCost) { final Map params = staticAbility.getMapParams(); final Card hostCard = staticAbility.getHostCard(); final Player activator = sa.getActivatingPlayer(); @@ -193,7 +334,7 @@ public class StaticAbilityCostChange { * @param originalCost * a ManaCost */ - public static void applyReduceCostAbility(final StaticAbility staticAbility, final SpellAbility sa, final ManaCostBeingPaid manaCost) { + private static void applyReduceCostAbility(final StaticAbility staticAbility, final SpellAbility sa, final ManaCostBeingPaid manaCost) { //Can't reduce zero cost if (manaCost.toString().equals("{0}")) { return; @@ -292,5 +433,6 @@ public class StaticAbilityCostChange { manaCost.decreaseShard(ManaCostShard.GREEN, value); } } - } -} + } + +} \ No newline at end of file diff --git a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java index bf8e42ecd0b..06d09f792a2 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java @@ -19,20 +19,12 @@ package forge.game.mana; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; + import forge.card.ColorSet; import forge.card.MagicColor; import forge.card.mana.IParserManaCost; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.game.staticability.StaticAbility; -import forge.game.zone.ZoneType; import forge.util.maps.EnumMapToAmount; import forge.util.maps.MapToAmount; @@ -488,128 +480,6 @@ public class ManaCostBeingPaid { unpaidShards.remove(ManaCostShard.COLORLESS); } - public final void applySpellCostChange(final SpellAbility sa, boolean test) { - final Game game = sa.getActivatingPlayer().getGame(); - // Beached - final Card originalCard = sa.getHostCard(); - final SpellAbility spell = sa; - - if (sa.isXCost() && !originalCard.isCopiedSpell()) { - originalCard.setXManaCostPaid(0); - } - - if (sa.isTrigger()) { - return; - } - - if (spell.isSpell()) { - if (spell.isDelve()) { - final Player pc = originalCard.getController(); - final List mutableGrave = new ArrayList(pc.getCardsIn(ZoneType.Graveyard)); - final List toExile = pc.getController().chooseCardsToDelve(this.getColorlessManaAmount(), mutableGrave); - for (final Card c : toExile) { - decreaseColorlessMana(1); - if (!test) { - pc.getGame().getAction().exile(c); - } - } - } - else if (spell.getHostCard().hasKeyword("Convoke")) { - adjustCostByConvoke(sa); - } - } // isSpell - - List cardsOnBattlefield = Lists.newArrayList(game.getCardsIn(ZoneType.Battlefield)); - cardsOnBattlefield.addAll(game.getCardsIn(ZoneType.Stack)); - cardsOnBattlefield.addAll(game.getCardsIn(ZoneType.Command)); - if (!cardsOnBattlefield.contains(originalCard)) { - cardsOnBattlefield.add(originalCard); - } - final ArrayList raiseAbilities = new ArrayList(); - final ArrayList reduceAbilities = new ArrayList(); - final ArrayList setAbilities = new ArrayList(); - - // Sort abilities to apply them in proper order - for (Card c : cardsOnBattlefield) { - final ArrayList staticAbilities = c.getStaticAbilities(); - for (final StaticAbility stAb : staticAbilities) { - if (stAb.getMapParams().get("Mode").equals("RaiseCost")) { - raiseAbilities.add(stAb); - } - else if (stAb.getMapParams().get("Mode").equals("ReduceCost")) { - reduceAbilities.add(stAb); - } - else if (stAb.getMapParams().get("Mode").equals("SetCost")) { - setAbilities.add(stAb); - } - } - } - // Raise cost - for (final StaticAbility stAb : raiseAbilities) { - stAb.applyAbility("RaiseCost", spell, this); - } - - // Reduce cost - for (final StaticAbility stAb : reduceAbilities) { - stAb.applyAbility("ReduceCost", spell, this); - } - if (spell.isSpell() && spell.isOffering()) { // cost reduction from offerings - adjustCostByOffering(sa, spell); - } - - // Set cost (only used by Trinisphere) is applied last - for (final StaticAbility stAb : setAbilities) { - stAb.applyAbility("SetCost", spell, this); - } - } // GetSpellCostChange - - private void adjustCostByConvoke(final SpellAbility sa) { - - List untappedCreats = CardLists.filter(sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); - untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED); - - Map convokedCards = sa.getActivatingPlayer().getController().chooseCardsForConvoke(sa, this.toManaCost(), untappedCreats); - - // Convoked creats are tapped here with triggers suppressed, - // Then again when payment is done(In InputPayManaCost.done()) with suppression cleared. - // This is to make sure that triggers go off at the right time - // AND that you can't use mana tapabilities of convoked creatures to pay the convoked cost. - for (final Entry conv : convokedCards.entrySet()) { - sa.addTappedForConvoke(conv.getKey()); - this.decreaseShard(conv.getValue(), 1); - conv.getKey().setTapped(true); - } - } - - private void adjustCostByOffering(final SpellAbility sa, final SpellAbility spell) { - String offeringType = ""; - for (String kw : sa.getHostCard().getKeyword()) { - if (kw.endsWith(" offering")) { - offeringType = kw.split(" ")[0]; - break; - } - } - - Card toSac = null; - List canOffer = CardLists.filter(spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), - CardPredicates.isType(offeringType)); - - final List toSacList = sa.getHostCard().getController().getController().choosePermanentsToSacrifice(spell, 0, 1, canOffer, - offeringType); - - if (!toSacList.isEmpty()) { - toSac = toSacList.get(0); - } - else { - return; - } - - subtractManaCost(toSac.getManaCost()); - - sa.setSacrificedAsOffering(toSac); - toSac.setUsedToPay(true); //stop it from interfering with mana input - } - public String getSourceRestriction() { return sourceRestriction; } diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index d58c32c0af1..8b5176e10dc 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -222,10 +222,10 @@ public abstract class PlayerController { public List cheatShuffle(List list) { return list; } public Collection complainCardsCantPlayWell(Deck myDeck) { return null; } - public final boolean payManaCost(CostPartMana costPartMana, SpellAbility sa, String prompt) { - return payManaCost(costPartMana.getManaCostFor(sa), costPartMana, sa, prompt); + public final boolean payManaCost(CostPartMana costPartMana, SpellAbility sa, String prompt, boolean isActivatedAbility) { + return payManaCost(costPartMana.getManaCostFor(sa), costPartMana, sa, prompt, isActivatedAbility); } - public abstract boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt); + public abstract boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt, boolean isActivatedAbility); public abstract Map chooseCardsForConvoke(SpellAbility sa, ManaCost manaCost, List untappedCreats); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index 9f9dfdbcf16..02982de4d35 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -23,7 +23,6 @@ import forge.game.GameEntity; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.cost.Cost; -import forge.game.mana.ManaCostBeingPaid; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -324,38 +323,6 @@ public class StaticAbility extends CardTraitBase { return false; } - /** - * Apply ability. - * - * @param mode - * the mode - * @param sa - * the SpellAbility - * @param originalCost - * the originalCost - * @return the modified ManaCost - */ - public final void applyAbility(final String mode, final SpellAbility sa, final ManaCostBeingPaid originalCost) { - - // don't apply the ability if it hasn't got the right mode - if (!this.mapParams.get("Mode").equals(mode)) { - return; - } - - if (this.isSuppressed() || !this.checkConditions()) { - return; - } - - if (mode.equals("RaiseCost")) { - StaticAbilityCostChange.applyRaiseCostAbility(this, sa, originalCost); - } - if (mode.equals("ReduceCost")) { - StaticAbilityCostChange.applyReduceCostAbility(this, sa, originalCost); - } - if (mode.equals("SetCost")) { //Set cost is only used by Trinisphere - StaticAbilityCostChange.applyRaiseCostAbility(this, sa, originalCost); - } - } /** * Apply ability. diff --git a/forge-gui/src/main/java/forge/gui/player/HumanPlay.java b/forge-gui/src/main/java/forge/gui/player/HumanPlay.java index f7ed8c3bf01..102bd8836ff 100644 --- a/forge-gui/src/main/java/forge/gui/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/gui/player/HumanPlay.java @@ -1,6 +1,7 @@ package forge.gui.player; import com.google.common.base.Predicate; + import forge.FThreads; import forge.card.MagicColor; import forge.card.mana.ManaCost; @@ -15,6 +16,7 @@ import forge.game.ability.effects.FlipCoinEffect; import forge.game.card.*; import forge.game.card.CardPredicates.Presets; import forge.game.cost.*; +import forge.game.mana.ManaCostAdjustment; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.spellability.Ability; @@ -24,6 +26,7 @@ import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.input.*; import forge.util.Lang; + import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; @@ -124,7 +127,7 @@ public class HumanPlay { } else { manaCost = new ManaCostBeingPaid(sa.getPayCosts().getTotalMana()); - manaCost.applySpellCostChange(sa, false); + ManaCostAdjustment.adjust(manaCost, sa, false); } boolean isPaid = manaCost.isPaid(); @@ -627,8 +630,9 @@ public class HumanPlay { prompt = source + "\n" + promptCurrent; } - sourceAbility.clearManaPaid(); - boolean paid = p.getController().payManaCost(cost.getCostMana(), sourceAbility, prompt); + if( sourceAbility != null ) + sourceAbility.clearManaPaid(); + boolean paid = p.getController().payManaCost(cost.getCostMana(), sourceAbility, prompt, false); if (!paid) { p.getManaPool().refundManaPaid(sourceAbility); } @@ -679,7 +683,7 @@ public class HumanPlay { return done; } - public static boolean payManaCost(final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt) { + public static boolean payManaCost(final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt, boolean isActivatedSa) { final Card source = ability.getHostCard(); ManaCostBeingPaid toPay = new ManaCostBeingPaid(realCost, mc.getRestiction()); @@ -699,8 +703,8 @@ public class HumanPlay { toPay.addManaCost(mkCost); } - - toPay.applySpellCostChange(ability, false); + if( isActivatedSa ) + ManaCostAdjustment.adjust(toPay, ability, false); InputPayMana inpPayment; if (ability.isOffering() && ability.getSacrificedAsOffering() == null) { diff --git a/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java index f1aa75624ea..ce287661b81 100644 --- a/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java @@ -957,8 +957,7 @@ public class PlayerControllerHuman extends PlayerController { @Override public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List allPayers) { // if it's paid by the AI already the human can pay, but it won't change anything - final Card source = sa.getHostCard(); - return HumanPlay.payCostDuringAbilityResolve(player, source, cost, sa, null); + return HumanPlay.payCostDuringAbilityResolve(player, sa.getHostCard(), cost, sa, null); } @Override @@ -1062,8 +1061,8 @@ public class PlayerControllerHuman extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */ ) { - return HumanPlay.payManaCost(toPay, costPartMana, sa, player, prompt); + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt, boolean isActivatedSa) { + return HumanPlay.payManaCost(toPay, costPartMana, sa, player, prompt, isActivatedSa); } @Override diff --git a/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 2055ca683a7..b5e86edfd8e 100644 --- a/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -566,9 +566,10 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */ ) { + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa ) { // TODO Auto-generated method stub - return ComputerUtilMana.payManaCost(new ManaCostBeingPaid(toPay), sa, player); + ManaCostBeingPaid cost = new ManaCostBeingPaid(toPay); + return ComputerUtilMana.payManaCost(cost, sa, player); } @Override