diff --git a/.gitattributes b/.gitattributes index d85293e4570..6dcd4200fec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6393,6 +6393,7 @@ res/cardsfolder/m/multani_maro_sorcerer.txt svneol=native#text/plain res/cardsfolder/m/multanis_acolyte.txt svneol=native#text/plain res/cardsfolder/m/multanis_decree.txt svneol=native#text/plain res/cardsfolder/m/multanis_harmony.txt -text svneol=unset#text/plain +res/cardsfolder/m/mundungu.txt -text res/cardsfolder/m/mungha_wurm.txt svneol=native#text/plain res/cardsfolder/m/muraganda_petroglyphs.txt svneol=native#text/plain res/cardsfolder/m/murasa_pyromancer.txt svneol=native#text/plain diff --git a/res/cardsfolder/m/mundungu.txt b/res/cardsfolder/m/mundungu.txt new file mode 100644 index 00000000000..71a9a9a57bd --- /dev/null +++ b/res/cardsfolder/m/mundungu.txt @@ -0,0 +1,11 @@ +Name:Mundungu +ManaCost:1 U B +Types:Creature Human Wizard +PT:1/1 +Text:no text +A:AB$ Counter | Cost$ T | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 1 PayLife<1> | SpellDescription$ Counter target spell unless its controller pays 1 and 1 life. +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/mundungu.jpg +SetInfo:VIS|Uncommon|http://magiccards.info/scans/en/vi/132.jpg +Oracle:{T}: Counter target spell unless its controller pays {1} and 1 life. +End \ No newline at end of file diff --git a/src/main/java/forge/GameActionUtil.java b/src/main/java/forge/GameActionUtil.java index ea8bc812735..ade42d350e5 100644 --- a/src/main/java/forge/GameActionUtil.java +++ b/src/main/java/forge/GameActionUtil.java @@ -369,9 +369,7 @@ public final class GameActionUtil { final Command unpaid, SpellAbility sourceAbility) { final Card source = ability.getSourceCard(); final ArrayList parts = cost.getCostParts(); - if (parts.size() > 1) { - throw new RuntimeException("GameActionUtil::payCostDuringAbilityResolve - Too many payment types - " + source); - } + ArrayList remainingParts = new ArrayList(cost.getCostParts()); CostPart costPart = null; if (!parts.isEmpty()) { costPart = parts.get(0); @@ -384,60 +382,72 @@ public final class GameActionUtil { } return; } + boolean hasPaid = true; + //the three following costs do not need inputs + for (CostPart part : parts) { + if (part instanceof CostPayLife) { + String amountString = part.getAmount(); - if (costPart instanceof CostPayLife) { - String amountString = costPart.getAmount(); - //CardFactoryUtil.xCount(source, source.getSVar(amountString)) - - final int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) - : AbilityFactory.calculateAmount(source, amountString, sourceAbility); - Player p = Singletons.getControl().getPlayer(); - if (p.canPayLife(amount) && showYesNoDialog(source, "Do you want to pay " + amount + " life?")) { - p.payLife(amount, null); - paid.execute(); - } else { - unpaid.execute(); - } - return; - } - - if (costPart instanceof CostDamage) { - String amountString = costPart.getAmount(); - final int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) - : CardFactoryUtil.xCount(source, source.getSVar(amountString)); - Player p = Singletons.getControl().getPlayer(); - if (p.canPayLife(amount) && showYesNoDialog(source, "Do you want " + source + " to deal " + amount + " damage to you?")) { - p.addDamage(amount, source); - paid.execute(); - } else { - unpaid.execute(); - } - return; - } - - else if (costPart instanceof CostPutCounter) { - String amountString = costPart.getAmount(); - Counters counterType = ((CostPutCounter) costPart).getCounter(); - int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) - : CardFactoryUtil.xCount(source, source.getSVar(amountString)); - String plural = amount > 1 ? "s" : ""; - if (showYesNoDialog(source, "Do you want to put " + amount + " " + counterType.getName() - + " counter" + plural + " on " + source + "?")) { - if (source.canHaveCountersPlacedOnIt(counterType)) { - source.addCounterFromNonEffect(counterType, amount); - paid.execute(); + final int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) + : AbilityFactory.calculateAmount(source, amountString, sourceAbility); + Player p = Singletons.getControl().getPlayer(); + if (p.canPayLife(amount) && showYesNoDialog(source, "Do you want to pay " + amount + " life?")) { + p.payLife(amount, null); } else { - unpaid.execute(); - AllZone.getGameLog().add("ResolveStack", "Trying to pay upkeep for " + source + " but it can't have " - + counterType.getName() + " counters put on it.", 2); + hasPaid = false; } - } else { - unpaid.execute(); + remainingParts.remove(part); } + + else if (part instanceof CostDamage) { + String amountString = part.getAmount(); + final int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) + : CardFactoryUtil.xCount(source, source.getSVar(amountString)); + Player p = Singletons.getControl().getPlayer(); + if (p.canPayLife(amount) && showYesNoDialog(source, "Do you want " + source + " to deal " + amount + " damage to you?")) { + p.addDamage(amount, source); + } else { + hasPaid = false; + } + remainingParts.remove(part); + } + + else if (part instanceof CostPutCounter) { + String amountString = part.getAmount(); + Counters counterType = ((CostPutCounter) part).getCounter(); + int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) + : CardFactoryUtil.xCount(source, source.getSVar(amountString)); + String plural = amount > 1 ? "s" : ""; + if (showYesNoDialog(source, "Do you want to put " + amount + " " + counterType.getName() + + " counter" + plural + " on " + source + "?")) { + if (source.canHaveCountersPlacedOnIt(counterType)) { + source.addCounterFromNonEffect(counterType, amount); + } else { + hasPaid = false; + AllZone.getGameLog().add("ResolveStack", "Trying to pay upkeep for " + source + " but it can't have " + + counterType.getName() + " counters put on it.", 2); + } + } else { + hasPaid = false; + } + remainingParts.remove(part); + } + } + if (!hasPaid) { + unpaid.execute(); + return; + } + if (remainingParts.isEmpty()) { + paid.execute(); return; } + if (remainingParts.size() > 1) { + throw new RuntimeException("GameActionUtil::payCostDuringAbilityResolve - Too many payment types - " + source); + } + costPart = remainingParts.get(0); - else if (costPart instanceof CostSacrifice) { + //the following costs need inputs and can't be combined at the moment + if (costPart instanceof CostSacrifice) { final boolean bResolving = AllZone.getStack().getResolving(); AllZone.getStack().setResolving(false); AllZone.getInputControl().setInput(new InputPaySacCost((CostSacrifice) costPart, ability, paid, unpaid)); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java index a9b7cdd3114..8a3a9ebf652 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java @@ -285,7 +285,7 @@ public class AbilityFactoryCounterMagic { return false; } - if (this.unlessCost != null && !this.unlessCost.startsWith("Damage")) { + if (this.unlessCost != null && !this.unlessCost.endsWith(">")) { // Is this Usable Mana Sources? Or Total Available Mana? final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent()); int toPay = 0; diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index 17892cb68f3..afef5ff2ec7 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -212,7 +212,7 @@ public class ComputerUtil { // Unless Cost gets significant bonus + 10-Payment Amount final String unless = params.get("UnlessCost"); - if (unless != null && !unless.startsWith("Damage")) { + if (unless != null && !unless.endsWith(">")) { final int amount = AbilityFactory.calculateAmount(source, unless, sa); final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());