Removed 'YChoice' from game. - Tetravus may use the same variable X (it's cleared after resolve) no other cards used it

Fixed NPE in announce code for costs that do announce but have no manacost (ab of simic manipulator)
This commit is contained in:
Maxmtg
2013-04-08 07:38:49 +00:00
parent 3549a29040
commit 2511bda8bc
10 changed files with 21 additions and 51 deletions

View File

@@ -3,7 +3,7 @@ ManaCost:1 U U
Types:Creature Merfolk Types:Creature Merfolk
PT:0/1 PT:0/1
K:Evolve K:Evolve
A:AB$ GainControl | Announce$ X | Cost$ XCantBe0 T SubCounter<X/P1P1/CARDNAME> | ValidTgts$ Creature.powerLEX | TgtPrompt$ Select target with power less than or equal to the number of +1/+1 counters removed this way | SpellDescription$ Gain control of target creature with power less than or equal to the number of +1/+1 counters removed this way. A:AB$ GainControl | Announce$ X | Cost$ XCantBe0 T SubCounter<X/P1P1> | ValidTgts$ Creature.powerLEX | TgtPrompt$ Select target with power less than or equal to the number of +1/+1 counters removed this way | SpellDescription$ Gain control of target creature with power less than or equal to the number of +1/+1 counters removed this way.
SVar:X:Count$xPaid SVar:X:Count$xPaid
SVar:RemAIDeck:True SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/simic_manipulator.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/simic_manipulator.jpg

View File

@@ -9,9 +9,7 @@ SVar:TrigToken:AB$Token | Cost$ SubCounter<X/P1P1> | References$ X | TokenAmount
SVar:DBClearXChoice:DB$ Cleanup | ClearChosenX$ True SVar:DBClearXChoice:DB$ Cleanup | ClearChosenX$ True
SVar:X:XChoice SVar:X:XChoice
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounters | TriggerDescription$ At the beginning of your upkeep, you may exile any number of tokens put onto the battlefield with CARDNAME. If you do, put that many +1/+1 counters on CARDNAME. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounters | TriggerDescription$ At the beginning of your upkeep, you may exile any number of tokens put onto the battlefield with CARDNAME. If you do, put that many +1/+1 counters on CARDNAME.
SVar:TrigPutCounters:AB$PutCounter | Cost$ Exile<Y/Creature.IsRemembered/Tetravite> | References$ Y | Defined$ Self | CounterType$ P1P1 | CounterNum$ ChosenY | CostDesc$ Exile any number of tokens put onto the battlefield with CARDNAME. | SubAbility$ DBClearYChoice SVar:TrigPutCounters:AB$PutCounter | Cost$ Exile<X/Creature.IsRemembered/Tetravite> | References$ X | Defined$ Self | CounterType$ P1P1 | CounterNum$ ChosenX | CostDesc$ Exile any number of tokens put onto the battlefield with CARDNAME. | SubAbility$ DBClearXChoice
SVar:DBClearYChoice:DB$ Cleanup | ClearChosenY$ True
SVar:Y:YChoice
SVar:Picture:http://www.wizards.com/global/images/magic/general/tetravus.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/tetravus.jpg
Oracle:Flying\nTetravus enters the battlefield with three +1/+1 counters on it.\nAt the beginning of your upkeep, you may remove any number of +1/+1 counters from Tetravus. If you do, put that many 1/1 colorless Tetravite artifact creature tokens onto the battlefield. They each have flying and "This creature can't be enchanted."\nAt the beginning of your upkeep, you may exile any number of tokens put onto the battlefield with Tetravus. If you do, put that many +1/+1 counters on Tetravus. Oracle:Flying\nTetravus enters the battlefield with three +1/+1 counters on it.\nAt the beginning of your upkeep, you may remove any number of +1/+1 counters from Tetravus. If you do, put that many 1/1 colorless Tetravite artifact creature tokens onto the battlefield. They each have flying and "This creature can't be enchanted."\nAt the beginning of your upkeep, you may exile any number of tokens put onto the battlefield with Tetravus. If you do, put that many +1/+1 counters on Tetravus.
SetInfo:ATQ Rare SetInfo:ATQ Rare

View File

@@ -226,7 +226,7 @@ public class Card extends GameEntity implements Comparable<Card> {
private final List<Command> untapCommandList = new ArrayList<Command>(); private final List<Command> untapCommandList = new ArrayList<Command>();
private final List<Command> changeControllerCommandList = new ArrayList<Command>(); private final List<Command> changeControllerCommandList = new ArrayList<Command>();
private final static ImmutableList<String> storableSVars = ImmutableList.of("ChosenX", "ChosenY" ); private final static ImmutableList<String> storableSVars = ImmutableList.of("ChosenX" );
private final List<Card> hauntedBy = new ArrayList<Card>(); private final List<Card> hauntedBy = new ArrayList<Card>();
private Card haunting = null; private Card haunting = null;

View File

@@ -318,7 +318,7 @@ public class AbilityUtils {
if (StringUtils.isBlank(svarval)) { if (StringUtils.isBlank(svarval)) {
// Some variables may be not chosen yet at this moment // Some variables may be not chosen yet at this moment
// So return 0 and don't issue an error. // So return 0 and don't issue an error.
if (amount.equals("ChosenX") || amount.equals("ChosenY")) { if (amount.equals("ChosenX")) {
// isn't made yet // isn't made yet
return 0; return 0;
} }

View File

@@ -31,9 +31,6 @@ public class CleanUpEffect extends SpellAbilityEffect {
if (sa.hasParam("ClearChosenX")) { if (sa.hasParam("ClearChosenX")) {
source.setSVar("ChosenX", ""); source.setSVar("ChosenX", "");
} }
if (sa.hasParam("ClearChosenY")) {
source.setSVar("ChosenY", "");
}
if (sa.hasParam("ClearTriggered")) { if (sa.hasParam("ClearTriggered")) {
Singletons.getModel().getGame().getTriggerHandler().clearDelayedTrigger(source); Singletons.getModel().getGame().getTriggerHandler().clearDelayedTrigger(source);
} }

View File

@@ -542,8 +542,6 @@ public class CostExile extends CostPartWithList {
// Generalize this // Generalize this
if (sVar.equals("XChoice")) { if (sVar.equals("XChoice")) {
c = CostUtil.chooseXValue(source, ability, list.size()); c = CostUtil.chooseXValue(source, ability, list.size());
} else if (sVar.equals("YChoice")) {
c = CostUtil.chooseYValue(source, ability, list.size());
} else { } else {
c = AbilityUtils.calculateAmount(source, amount, ability); c = AbilityUtils.calculateAmount(source, amount, ability);
} }
@@ -652,7 +650,7 @@ public class CostExile extends CostPartWithList {
if (c == null) { if (c == null) {
final String sVar = ability.getSVar(this.getAmount()); final String sVar = ability.getSVar(this.getAmount());
// Generalize this // Generalize this
if (sVar.equals("XChoice") || sVar.equals("YChoice")) { if (sVar.equals("XChoice")) {
return null; return null;
} }
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability); c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);

View File

@@ -122,21 +122,23 @@ public class CostRemoveCounter extends CostPartWithList {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard(); final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
int maxCounters = 0;
String sVarAmount = ability.getSVar(amount);
cntRemoved = 1; cntRemoved = 1;
if (amount.equals("All")) if (c != null)
cntRemoved = -1;
else if (c != null) {
cntRemoved = c.intValue(); cntRemoved = c.intValue();
} else { else if (!"XChoice".equals(sVarAmount)) {
cntRemoved = "XChoice".equals(ability.getSVar(amount)) cntRemoved = AbilityUtils.calculateAmount(source, amount, ability);
? CostUtil.chooseXValue(source, ability, maxCounters)
: AbilityUtils.calculateAmount(source, amount, ability);
} }
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
maxCounters = source.getCounters(this.counter); int maxCounters = source.getCounters(this.counter);
if (amount.equals("All"))
cntRemoved = maxCounters;
else if ( c == null && "XChoice".equals(sVarAmount)) {
cntRemoved = CostUtil.chooseXValue(source, ability, maxCounters);
}
if (maxCounters < cntRemoved) if (maxCounters < cntRemoved)
return false; return false;
cntRemoved = cntRemoved >= 0 ? cntRemoved : maxCounters; cntRemoved = cntRemoved >= 0 ? cntRemoved : maxCounters;

View File

@@ -97,33 +97,6 @@ public class CostUtil {
return chosenX; return chosenX;
} }
/**
* Choose x value (for ChosenY).
*
* @param card
* the card
* @param sa
* the SpellAbility
* @param maxValue
* the max value
* @return the int
*/
public static int chooseYValue(final Card card, final SpellAbility sa, final int maxValue) {
/*final String chosen = sa.getSVar("ChosenY");
if (chosen.length() > 0) {
return AbilityFactory.calculateAmount(card, "ChosenY", null);
}*/
final Integer[] choiceArray = new Integer[maxValue + 1];
for (int i = 0; i < choiceArray.length; i++) {
choiceArray[i] = Integer.valueOf(i);
}
final Integer chosenY = GuiChoose.one(card.toString() + " - Choose a Value for Y", choiceArray);
sa.setSVar("ChosenY", Integer.toString(chosenY));
card.setSVar("ChosenY", Integer.toString(chosenY));
return chosenY;
}
public static Cost combineCosts(Cost cost1, Cost cost2) { public static Cost combineCosts(Cost cost1, Cost cost2) {
if (cost1 == null) return cost2; if (cost1 == null) return cost2;

View File

@@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
import forge.Card; import forge.Card;
import forge.CardCharacteristicName; import forge.CardCharacteristicName;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.cost.CostPartMana;
import forge.card.cost.CostPayment; import forge.card.cost.CostPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.zone.Zone; import forge.game.zone.Zone;
@@ -157,7 +158,9 @@ public class HumanPlaySpellAbility {
for(String aVar : announce.split(",")) { for(String aVar : announce.split(",")) {
String varName = aVar.trim(); String varName = aVar.trim();
boolean allowZero = !("X".equalsIgnoreCase(varName)) || ability.getPayCosts().getCostMana().canXbe0(); boolean isX = "X".equalsIgnoreCase(varName);
CostPartMana manaCost = ability.getPayCosts().getCostMana();
boolean allowZero = !isX || manaCost == null || manaCost.canXbe0();
Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, varName, allowZero); Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, varName, allowZero);
if ( null == value ) if ( null == value )

View File

@@ -26,7 +26,6 @@ import com.esotericsoftware.minlog.Log;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads; import forge.FThreads;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.Singletons; import forge.Singletons;