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
This commit is contained in:
Maxmtg
2013-02-10 08:09:14 +00:00
parent aab0858623
commit 16f3008014
6 changed files with 56 additions and 44 deletions

1
.gitattributes vendored
View File

@@ -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

View File

@@ -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

View File

@@ -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<Player> 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();
}
}

View File

@@ -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),

View File

@@ -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<Card> getTargetCards(SpellAbility sa) {
final Target tgt = sa.getTarget();
return tgt != null ? tgt.getTargetCards() : AbilityFactory.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);

View File

@@ -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<Player> targets = getDefinedPlayersBeforeTargetOnes(sa);
for(Player p : targets) {
int taken = p.getManaPool().clearPool(false);
if ( "True".equalsIgnoreCase(sa.getParam("TakeDamage")) )
p.addDamage(taken, sa.getSourceCard());
}
}
}