From 16f3008014be8a6b0a3e70acb04d4ce10769e5da Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Sun, 10 Feb 2013 08:09:14 +0000 Subject: [PATCH] Power sink: reviewed script, so that correct effect (DrainMana) is used Unless syntax enriched: added UnlessResolveSubs parameter to indicate if subAbilities are resolved for paid and unpaid branches SpellDesciptions from card scripts now may include variables --- .gitattributes | 1 - res/cardsfolder/p/power_sink.txt | 6 ++-- .../card/abilityfactory/AbilityFactory.java | 30 +++++++++------- .../forge/card/abilityfactory/ApiType.java | 1 - .../card/abilityfactory/SpellEffect.java | 36 ++++++++++++++++++- .../effects/ManaBurnEffect.java | 26 -------------- 6 files changed, 56 insertions(+), 44 deletions(-) delete mode 100644 src/main/java/forge/card/abilityfactory/effects/ManaBurnEffect.java diff --git a/.gitattributes b/.gitattributes index 62a6988740b..11dd4d2fdde 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13676,7 +13676,6 @@ src/main/java/forge/card/abilityfactory/effects/LifeExchangeEffect.java -text src/main/java/forge/card/abilityfactory/effects/LifeGainEffect.java -text src/main/java/forge/card/abilityfactory/effects/LifeLoseEffect.java -text src/main/java/forge/card/abilityfactory/effects/LifeSetEffect.java -text -src/main/java/forge/card/abilityfactory/effects/ManaBurnEffect.java -text src/main/java/forge/card/abilityfactory/effects/ManaEffect.java -text src/main/java/forge/card/abilityfactory/effects/ManaReflectedEffect.java -text src/main/java/forge/card/abilityfactory/effects/MillEffect.java -text diff --git a/res/cardsfolder/p/power_sink.txt b/res/cardsfolder/p/power_sink.txt index a2105598999..0fa78d2fa48 100644 --- a/res/cardsfolder/p/power_sink.txt +++ b/res/cardsfolder/p/power_sink.txt @@ -2,9 +2,9 @@ Name:Power Sink ManaCost:X U Types:Instant Text:no text -A:SP$ Counter | Cost$ X U | References$ X | UnlessCost$ X | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SubAbility$ TapLands | SpellDescription$ Counter target spell unless its controller pays X. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool. -SVar:TapLands:DB$ TapAll | ValidCards$ Land.hasManaAbility | Defined$ TargetedController | SubAbility$ ManaLose -SVar:ManaLose:DB$ ManaBurn | TakeDamage$ False | Defined$ TargetedController +A:SP$ Counter | Cost$ X U | References$ X | UnlessCost$ X | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SubAbility$ TapLands | UnlessResolveSubs$ WhenNotPaid | SpellDescription$ Counter target spell unless its controller pays X. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool. | StackDescription$ Countering [{s:Targeted}] unless {p:TargetedController} pays X. +SVar:TapLands:DB$ TapAll | ValidCards$ Land.hasManaAbility | Defined$ TargetedController | SubAbility$ ManaLose| StackDescription$ If {p:TargetedController} doesn't, that player taps all lands with mana abilities he or she controls and +SVar:ManaLose:DB$ DrainMana | Defined$ TargetedController SVar:X:Count$xPaid SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/power_sink.jpg diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index 87ebb8b567e..3eef1ed3225 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -23,6 +23,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import forge.Card; import forge.CardLists; @@ -1377,19 +1379,23 @@ public class AbilityFactory { public static void passUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) { final Card source = sa.getSourceCard(); final ApiType api = sa.getApi(); - if (api == null || sa.getParam("UnlessCost") == null) { + String unlessCost = sa.getParam("UnlessCost"); + + if (StringUtils.isBlank(unlessCost) || api == null) { sa.resolve(); AbilityFactory.resolveSubAbilities(sa, usedStack, game); return; } + unlessCost = unlessCost.trim(); // The player who has the chance to cancel the ability final String pays = sa.hasParam("UnlessPayer") ? sa.getParam("UnlessPayer") : "TargetedController"; final List payers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), pays, sa); + final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always' + final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); + final boolean execSubsWhenNotPaid = "WhenNotPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); // The cost - String unlessCost = sa.getParam("UnlessCost").trim(); - if (unlessCost.equals("CardManaCost")) { unlessCost = source.getManaCost().toString(); } else { @@ -1401,12 +1407,15 @@ public class AbilityFactory { //instead of just X for cards like Draco. } + final boolean isSwitched = sa.hasParam("UnlessSwitched"); + Command paidCommand = new Command() { private static final long serialVersionUID = 8094833091127334678L; @Override public void execute() { - AbilityFactory.resolveSubAbilities(sa, usedStack, game); + if ( isSwitched && execSubsWhenNotPaid || execSubsWhenPaid) + AbilityFactory.resolveSubAbilities(sa, usedStack, game); } }; @@ -1416,11 +1425,12 @@ public class AbilityFactory { @Override public void execute() { sa.resolve(); - AbilityFactory.resolveSubAbilities(sa, usedStack, game); + if ( isSwitched && execSubsWhenPaid || execSubsWhenNotPaid) + AbilityFactory.resolveSubAbilities(sa, usedStack, game); } }; - if (sa.hasParam("UnlessSwitched")) { + if (isSwitched) { final Command dummy = paidCommand; paidCommand = unpaidCommand; unpaidCommand = dummy; @@ -1458,12 +1468,8 @@ public class AbilityFactory { } } if (!waitForInput) { - if (paid) { - AbilityFactory.resolveSubAbilities(sa, usedStack, game); - } else { - sa.resolve(); - AbilityFactory.resolveSubAbilities(sa, usedStack, game); - } + Command toExecute = paid ? paidCommand : unpaidCommand; + toExecute.execute(); } } diff --git a/src/main/java/forge/card/abilityfactory/ApiType.java b/src/main/java/forge/card/abilityfactory/ApiType.java index 761cabe4f35..ad0b0a6f420 100644 --- a/src/main/java/forge/card/abilityfactory/ApiType.java +++ b/src/main/java/forge/card/abilityfactory/ApiType.java @@ -60,7 +60,6 @@ public enum ApiType { LoseLife (LifeLoseEffect.class, LifeLoseAi.class), LosesGame (GameLossEffect.class, GameLossAi.class), Mana (ManaEffect.class, CannotPlayAi.class), - ManaBurn (ManaBurnEffect.class, CannotPlayAi.class), ManaReflected (ManaReflectedEffect.class, CannotPlayAi.class), Mill (MillEffect.class, MillAi.class), MoveCounter (CountersMoveEffect.class, CountersMoveAi.class), diff --git a/src/main/java/forge/card/abilityfactory/SpellEffect.java b/src/main/java/forge/card/abilityfactory/SpellEffect.java index 026e83d5f0a..4d92515804c 100644 --- a/src/main/java/forge/card/abilityfactory/SpellEffect.java +++ b/src/main/java/forge/card/abilityfactory/SpellEffect.java @@ -4,7 +4,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.StringTokenizer; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang3.StringUtils; import forge.Card; @@ -63,7 +65,7 @@ import forge.game.player.Player; if ("SpellDescription".equalsIgnoreCase(stackDesc)) { // by typing "none" they want to suppress output sb.append(params.get("SpellDescription").replace("CARDNAME", sa.getSourceCard().getName())); } else if (!"None".equalsIgnoreCase(stackDesc)) { // by typing "none" they want to suppress output - sb.append(stackDesc.replace("CARDNAME", sa.getSourceCard().getName())); + makeSpellDescription(sa, sb, stackDesc); } } else { final String conditionDesc = sa.getParam("ConditionDescription"); @@ -85,6 +87,38 @@ import forge.game.player.Player; return sb.toString(); } + /** + * TODO: Write javadoc for this method. + * @param sa + * @param sb + * @param stackDesc + */ + private void makeSpellDescription(final SpellAbility sa, StringBuilder sb, String stackDesc) { + StringTokenizer st = new StringTokenizer(stackDesc, "{}", true); + boolean isPlainText = true; + while( st.hasMoreTokens() ) + { + String t = st.nextToken(); + if ( "{".equals(t) ) { isPlainText = false; continue; } + if ( "}".equals(t) ) { isPlainText = true; continue; } + if ( isPlainText ) + sb.append(t.replace("CARDNAME", sa.getSourceCard().getName())); + else { + List objs = null; + if ( t.startsWith("p:") ) + objs = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), t.substring(2), sa); + else if ( t.startsWith("s:")) + objs = AbilityFactory.getDefinedSpellAbilities(sa.getSourceCard(), t.substring(2), sa); + else if ( t.startsWith("c:")) + objs = AbilityFactory.getDefinedCards(sa.getSourceCard(), t.substring(2), sa); + else + objs = AbilityFactory.getDefinedObjects(sa.getSourceCard(), t, sa); + + sb.append(StringUtils.join(objs, ", ")); + } + } + } + protected List getTargetCards(SpellAbility sa) { final Target tgt = sa.getTarget(); return tgt != null ? tgt.getTargetCards() : AbilityFactory.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); diff --git a/src/main/java/forge/card/abilityfactory/effects/ManaBurnEffect.java b/src/main/java/forge/card/abilityfactory/effects/ManaBurnEffect.java deleted file mode 100644 index 02bb02dcfac..00000000000 --- a/src/main/java/forge/card/abilityfactory/effects/ManaBurnEffect.java +++ /dev/null @@ -1,26 +0,0 @@ -package forge.card.abilityfactory.effects; - -import java.util.List; - -import forge.card.abilityfactory.SpellEffect; -import forge.card.spellability.SpellAbility; -import forge.game.player.Player; - - -// TakeDamage = will mana burnt be removed from life -// May also add filters on colors -public class ManaBurnEffect extends SpellEffect { - - @Override - public void resolve(SpellAbility sa) { - - List targets = getDefinedPlayersBeforeTargetOnes(sa); - for(Player p : targets) { - int taken = p.getManaPool().clearPool(false); - if ( "True".equalsIgnoreCase(sa.getParam("TakeDamage")) ) - p.addDamage(taken, sa.getSourceCard()); - } - - } - -}