Zabaz: add Cause to ReplaceAddCounter

This commit is contained in:
Hans Mackowiak
2021-06-11 08:31:21 +02:00
parent 8948210e0a
commit fc82dbb9aa
28 changed files with 78 additions and 59 deletions

View File

@@ -1630,7 +1630,7 @@ public class ComputerUtilCard {
pumped.addChangedCardKeywords(kws, null, false, false, timestamp); pumped.addChangedCardKeywords(kws, null, false, false, timestamp);
Set<CounterType> types = c.getCounters().keySet(); Set<CounterType> types = c.getCounters().keySet();
for(CounterType ct : types) { for(CounterType ct : types) {
pumped.addCounterFireNoEvents(ct, c.getCounters(ct), ai, true, null); pumped.addCounterFireNoEvents(ct, c.getCounters(ct), ai, sa, true, null);
} }
//Copies tap-state and extra keywords (auras, equipment, etc.) //Copies tap-state and extra keywords (auras, equipment, etc.)
if (c.isTapped()) { if (c.isTapped()) {

View File

@@ -1175,7 +1175,7 @@ public abstract class GameState {
String[] allCounterStrings = counterString.split(","); String[] allCounterStrings = counterString.split(",");
for (final String counterPair : allCounterStrings) { for (final String counterPair : allCounterStrings) {
String[] pair = counterPair.split("=", 2); String[] pair = counterPair.split("=", 2);
entity.addCounter(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, false, false, null); entity.addCounter(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, null, false, false, null);
} }
} }

View File

@@ -217,7 +217,7 @@ public class SpecialCardAi {
Card animated = AnimateAi.becomeAnimated(sa.getHostCard(), sa.getSubAbility()); Card animated = AnimateAi.becomeAnimated(sa.getHostCard(), sa.getSubAbility());
if (sa.getHostCard().canReceiveCounters(CounterEnumType.P1P1)) { if (sa.getHostCard().canReceiveCounters(CounterEnumType.P1P1)) {
animated.addCounter(CounterEnumType.P1P1, 2, ai, false, null); animated.addCounter(CounterEnumType.P1P1, 2, ai, sa.getSubAbility(), false, null);
} }
boolean isOppEOT = ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai; boolean isOppEOT = ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai;
boolean isValuableAttacker = ph.is(PhaseType.MAIN1, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated); boolean isValuableAttacker = ph.is(PhaseType.MAIN1, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated);

View File

@@ -155,6 +155,8 @@ public class ForgeScript {
return sa.isAftermath(); return sa.isAftermath();
} else if (property.equals("MorphUp")) { } else if (property.equals("MorphUp")) {
return sa.isMorphUp(); return sa.isMorphUp();
} else if (property.equals("Modular")) {
return sa.hasParam("Modular");
} else if (property.equals("Equip")) { } else if (property.equals("Equip")) {
return sa.hasParam("Equip"); return sa.hasParam("Equip");
} else if (property.equals("Boast")) { } else if (property.equals("Boast")) {

View File

@@ -1235,7 +1235,7 @@ public class GameAction {
int loyal = c.getCounters(CounterEnumType.LOYALTY); int loyal = c.getCounters(CounterEnumType.LOYALTY);
if (loyal < beeble) { if (loyal < beeble) {
GameEntityCounterTable counterTable = new GameEntityCounterTable(); GameEntityCounterTable counterTable = new GameEntityCounterTable();
c.addCounter(CounterEnumType.LOYALTY, beeble - loyal, c.getController(), false, counterTable); c.addCounter(CounterEnumType.LOYALTY, beeble - loyal, c.getController(), null, false, counterTable);
counterTable.triggerCountersPutAll(game); counterTable.triggerCountersPutAll(game);
} else if (loyal > beeble) { } else if (loyal > beeble) {
c.subtractCounter(CounterEnumType.LOYALTY, loyal - beeble); c.subtractCounter(CounterEnumType.LOYALTY, loyal - beeble);

View File

@@ -300,7 +300,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
abstract public void setCounters(final Map<CounterType, Integer> allCounters); abstract public void setCounters(final Map<CounterType, Integer> allCounters);
abstract public boolean canReceiveCounters(final CounterType type); abstract public boolean canReceiveCounters(final CounterType type);
abstract public int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table); abstract public int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table);
abstract public void subtractCounter(final CounterType counterName, final int n); abstract public void subtractCounter(final CounterType counterName, final int n);
abstract public void clearCounters(); abstract public void clearCounters();
@@ -308,8 +308,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
return canReceiveCounters(CounterType.get(type)); return canReceiveCounters(CounterType.get(type));
} }
public int addCounter(final CounterEnumType counterType, final int n, final Player source, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) { public int addCounter(final CounterEnumType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) {
return addCounter(CounterType.get(counterType), n, source, applyMultiplier, fireEvents, table); return addCounter(CounterType.get(counterType), n, source, cause, applyMultiplier, fireEvents, table);
} }
public void subtractCounter(final CounterEnumType counterName, final int n) { public void subtractCounter(final CounterEnumType counterName, final int n) {
subtractCounter(CounterType.get(counterName), n); subtractCounter(CounterType.get(counterName), n);

View File

@@ -93,7 +93,7 @@ public class AmassEffect extends TokenEffectBase {
GameEntityCounterTable table = new GameEntityCounterTable(); GameEntityCounterTable table = new GameEntityCounterTable();
for(final Card tgtCard : tgtCards) { for(final Card tgtCard : tgtCards) {
tgtCard.addCounter(CounterEnumType.P1P1, amount, activator, true, table); tgtCard.addCounter(CounterEnumType.P1P1, amount, activator, sa, true, table);
game.updateLastStateForCard(tgtCard); game.updateLastStateForCard(tgtCard);
if (remember) { if (remember) {

View File

@@ -709,7 +709,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("WithCountersType")) { if (sa.hasParam("WithCountersType")) {
CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
movedCard.addCounter(cType, cAmount, player, true, counterTable); movedCard.addCounter(cType, cAmount, player, sa, true, counterTable);
} }
if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) { if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) {

View File

@@ -163,7 +163,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
} }
} }
for (Map.Entry<CounterType, Integer> e : countersToAdd.entrySet()) { for (Map.Entry<CounterType, Integer> e : countersToAdd.entrySet()) {
dest.addCounter(e.getKey(), e.getValue(), player, true, table); dest.addCounter(e.getKey(), e.getValue(), player, sa, true, table);
} }
game.updateLastStateForCard(dest); game.updateLastStateForCard(dest);
@@ -225,7 +225,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
if (cnum > 0) { if (cnum > 0) {
source.subtractCounter(cType, cnum); source.subtractCounter(cType, cnum);
cur.addCounter(cType, cnum, player, true, table); cur.addCounter(cType, cnum, player, sa, true, table);
game.updateLastStateForCard(cur); game.updateLastStateForCard(cur);
updateSource = true; updateSource = true;
} }
@@ -311,7 +311,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
} }
for (Map.Entry<CounterType, Integer> e : countersToAdd.entrySet()) { for (Map.Entry<CounterType, Integer> e : countersToAdd.entrySet()) {
cur.addCounter(e.getKey(), e.getValue(), player, true, table); cur.addCounter(e.getKey(), e.getValue(), player, sa, true, table);
} }
game.updateLastStateForCard(cur); game.updateLastStateForCard(cur);
} }

View File

@@ -54,10 +54,10 @@ public class CountersMultiplyEffect extends SpellAbilityEffect {
continue; continue;
} }
if (counterType != null) { if (counterType != null) {
gameCard.addCounter(counterType, gameCard.getCounters(counterType) * n, player, true, table); gameCard.addCounter(counterType, gameCard.getCounters(counterType) * n, player, sa, true, table);
} else { } else {
for (Map.Entry<CounterType, Integer> e : gameCard.getCounters().entrySet()) { for (Map.Entry<CounterType, Integer> e : gameCard.getCounters().entrySet()) {
gameCard.addCounter(e.getKey(), e.getValue() * n, player, true, table); gameCard.addCounter(e.getKey(), e.getValue() * n, player, sa, true, table);
} }
} }
game.updateLastStateForCard(gameCard); game.updateLastStateForCard(gameCard);

View File

@@ -30,7 +30,7 @@ public class CountersNoteEffect extends SpellAbilityEffect {
if (mode.equals(MODE_STORE)) { if (mode.equals(MODE_STORE)) {
noteCounters(c, source); noteCounters(c, source);
} else if (mode.equals(MODE_LOAD)) { } else if (mode.equals(MODE_LOAD)) {
loadCounters(c, source, p, table); loadCounters(c, source, p, sa, table);
} }
} }
table.triggerCountersPutAll(game); table.triggerCountersPutAll(game);
@@ -44,13 +44,13 @@ public class CountersNoteEffect extends SpellAbilityEffect {
} }
} }
private void loadCounters(Card notee, Card source, final Player p, GameEntityCounterTable table) { private void loadCounters(Card notee, Card source, final Player p, final SpellAbility sa, GameEntityCounterTable table) {
for(Entry<String, String> svar : source.getSVars().entrySet()) { for(Entry<String, String> svar : source.getSVars().entrySet()) {
String key = svar.getKey(); String key = svar.getKey();
if (key.startsWith(NOTE_COUNTERS)) { if (key.startsWith(NOTE_COUNTERS)) {
notee.addCounter( notee.addCounter(
CounterType.getType(key.substring(NOTE_COUNTERS.length())), CounterType.getType(key.substring(NOTE_COUNTERS.length())),
Integer.parseInt(svar.getValue()), p, false, table); Integer.parseInt(svar.getValue()), p, sa, false, table);
} }
// TODO Probably should "remove" the svars that were temporarily used // TODO Probably should "remove" the svars that were temporarily used
} }

View File

@@ -48,7 +48,7 @@ public class CountersProliferateEffect extends SpellAbilityEffect {
GameEntityCounterTable table = new GameEntityCounterTable(); GameEntityCounterTable table = new GameEntityCounterTable();
for (final GameEntity ge : result) { for (final GameEntity ge : result) {
for (final CounterType ct : ge.getCounters().keySet()) { for (final CounterType ct : ge.getCounters().keySet()) {
ge.addCounter(ct, 1, p, true, true, table); ge.addCounter(ct, 1, p, sa, true, true, table);
} }
if (ge instanceof Card) { if (ge instanceof Card) {
Card c = (Card) ge; Card c = (Card) ge;

View File

@@ -71,7 +71,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
if (etbcounter) { if (etbcounter) {
tgtCard.addEtbCounter(CounterType.getType(type), counterAmount, placer); tgtCard.addEtbCounter(CounterType.getType(type), counterAmount, placer);
} else { } else {
tgtCard.addCounter(CounterType.getType(type), counterAmount, placer, inBattlefield, table); tgtCard.addCounter(CounterType.getType(type), counterAmount, placer, sa, inBattlefield, table);
} }
game.updateLastStateForCard(tgtCard); game.updateLastStateForCard(tgtCard);
} }

View File

@@ -226,10 +226,10 @@ public class CountersPutEffect extends SpellAbilityEffect {
if (eachExistingCounter) { if (eachExistingCounter) {
for (CounterType ct : choices) { for (CounterType ct : choices) {
if (obj instanceof Player) { if (obj instanceof Player) {
((Player) obj).addCounter(ct, counterAmount, placer, true, table); ((Player) obj).addCounter(ct, counterAmount, placer, sa, true, table);
} }
if (obj instanceof Card) { if (obj instanceof Card) {
gameCard.addCounter(ct, counterAmount, placer, true, table); gameCard.addCounter(ct, counterAmount, placer, sa, true, table);
} }
} }
continue; continue;
@@ -253,7 +253,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
for (Card c : AbilityUtils.getDefinedCards(card, sa.getParam("EachFromSource"), sa)) { for (Card c : AbilityUtils.getDefinedCards(card, sa.getParam("EachFromSource"), sa)) {
for (Entry<CounterType, Integer> cti : c.getCounters().entrySet()) { for (Entry<CounterType, Integer> cti : c.getCounters().entrySet()) {
if (gameCard != null && gameCard.canReceiveCounters(cti.getKey())) { if (gameCard != null && gameCard.canReceiveCounters(cti.getKey())) {
gameCard.addCounter(cti.getKey(), cti.getValue(), placer, true, table); gameCard.addCounter(cti.getKey(), cti.getValue(), placer, sa, true, table);
} }
} }
} }
@@ -338,7 +338,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
if (etbcounter) { if (etbcounter) {
gameCard.addEtbCounter(counterType, counterAmount, placer); gameCard.addEtbCounter(counterType, counterAmount, placer);
} else { } else {
int addedAmount = gameCard.addCounter(counterType, counterAmount, placer, true, table); int addedAmount = gameCard.addCounter(counterType, counterAmount, placer, sa, true, table);
if (addedAmount > 0) { if (addedAmount > 0) {
counterAdded = true; counterAdded = true;
} }
@@ -372,7 +372,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
if (etbcounter) { if (etbcounter) {
gameCard.addEtbCounter(counterType, counterAmount, placer); gameCard.addEtbCounter(counterType, counterAmount, placer);
} else { } else {
if (gameCard.addCounter(counterType, counterAmount, placer, false, table) > 0) { if (gameCard.addCounter(counterType, counterAmount, placer, sa, false, table) > 0) {
counterAdded = true; counterAdded = true;
} }
} }
@@ -388,7 +388,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
} else if (obj instanceof Player) { } else if (obj instanceof Player) {
// Add Counters to players! // Add Counters to players!
Player pl = (Player) obj; Player pl = (Player) obj;
pl.addCounter(counterType, counterAmount, placer, true, table); pl.addCounter(counterType, counterAmount, placer, sa, true, table);
} }
} }
} }

View File

@@ -111,7 +111,7 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect {
boolean apply = zone == null || zone.is(ZoneType.Battlefield) || zone.is(ZoneType.Stack); boolean apply = zone == null || zone.is(ZoneType.Battlefield) || zone.is(ZoneType.Stack);
tgtCard.addCounter(chosenType, counterAmount, pl, apply, table); tgtCard.addCounter(chosenType, counterAmount, pl, sa, apply, table);
} else { } else {
tgtCard.subtractCounter(chosenType, counterAmount); tgtCard.subtractCounter(chosenType, counterAmount);
} }

View File

@@ -336,7 +336,7 @@ public class DigEffect extends SpellAbilityEffect {
} else if (destZone1.equals(ZoneType.Exile)) { } else if (destZone1.equals(ZoneType.Exile)) {
if (sa.hasParam("ExileWithCounter")) { if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")),
1, player, true, counterTable); 1, player, sa, true, counterTable);
} }
c.setExiledWith(effectHost); c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController()); c.setExiledBy(effectHost.getController());
@@ -408,7 +408,7 @@ public class DigEffect extends SpellAbilityEffect {
if (destZone2 == ZoneType.Exile) { if (destZone2 == ZoneType.Exile) {
if (sa.hasParam("ExileWithCounter")) { if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")),
1, player, true, counterTable); 1, player, sa, true, counterTable);
} }
c.setExiledWith(effectHost); c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController()); c.setExiledBy(effectHost.getController());

View File

@@ -83,7 +83,7 @@ public class ExploreEffect extends SpellAbilityEffect {
// if the card is not more in the game anymore // if the card is not more in the game anymore
// this might still return true but its no problem // this might still return true but its no problem
if (game.getZoneOf(gamec).is(ZoneType.Battlefield) && gamec.equalsWithTimestamp(c)) { if (game.getZoneOf(gamec).is(ZoneType.Battlefield) && gamec.equalsWithTimestamp(c)) {
c.addCounter(CounterEnumType.P1P1, 1, pl, true, table); c.addCounter(CounterEnumType.P1P1, 1, pl, sa, true, table);
} }
} }

View File

@@ -55,7 +55,7 @@ public class SacrificeEffect extends SpellAbilityEffect {
} }
} else if (sa.hasParam("CumulativeUpkeep")) { } else if (sa.hasParam("CumulativeUpkeep")) {
GameEntityCounterTable table = new GameEntityCounterTable(); GameEntityCounterTable table = new GameEntityCounterTable();
card.addCounter(CounterEnumType.AGE, 1, activator, true, table); card.addCounter(CounterEnumType.AGE, 1, activator, sa, true, table);
table.triggerCountersPutAll(game); table.triggerCountersPutAll(game);

View File

@@ -160,7 +160,7 @@ public class SetStateEffect extends SpellAbilityEffect {
} }
game.fireEvent(new GameEventCardStatsChanged(gameCard)); game.fireEvent(new GameEventCardStatsChanged(gameCard));
if (sa.hasParam("Mega")) { if (sa.hasParam("Mega")) {
gameCard.addCounter(CounterEnumType.P1P1, 1, p, true, table); gameCard.addCounter(CounterEnumType.P1P1, 1, p, sa, true, table);
} }
if (remChanged) { if (remChanged) {
host.addRemembered(gameCard); host.addRemembered(gameCard);

View File

@@ -1382,21 +1382,21 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return true; return true;
} }
public final int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { public final int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, GameEntityCounterTable table) {
return addCounter(counterType, n, source, applyMultiplier, true, table); return addCounter(counterType, n, source, cause, applyMultiplier, true, table);
} }
public final int addCounterFireNoEvents(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { public final int addCounterFireNoEvents(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, GameEntityCounterTable table) {
return addCounter(counterType, n, source, applyMultiplier, false, table); return addCounter(counterType, n, source, cause, applyMultiplier, false, table);
} }
public final int addCounter(final CounterEnumType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { public final int addCounter(final CounterEnumType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, GameEntityCounterTable table) {
return addCounter(counterType, n, source, applyMultiplier, true, table); return addCounter(counterType, n, source, cause, applyMultiplier, true, table);
} }
public final int addCounterFireNoEvents(final CounterEnumType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { public final int addCounterFireNoEvents(final CounterEnumType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, GameEntityCounterTable table) {
return addCounter(counterType, n, source, applyMultiplier, false, table); return addCounter(counterType, n, source, cause, applyMultiplier, false, table);
} }
@Override @Override
public int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) { public int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) {
int addAmount = n; int addAmount = n;
if(addAmount <= 0 || !canReceiveCounters(counterType)) { if(addAmount <= 0 || !canReceiveCounters(counterType)) {
// As per rule 107.1b // As per rule 107.1b
@@ -1404,6 +1404,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this); final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
repParams.put(AbilityKey.Source, source); repParams.put(AbilityKey.Source, source);
repParams.put(AbilityKey.Cause, cause);
repParams.put(AbilityKey.CounterType, counterType); repParams.put(AbilityKey.CounterType, counterType);
repParams.put(AbilityKey.CounterNum, addAmount); repParams.put(AbilityKey.CounterNum, addAmount);
repParams.put(AbilityKey.EffectOnly, applyMultiplier); repParams.put(AbilityKey.EffectOnly, applyMultiplier);
@@ -5273,7 +5274,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|| source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT)); || source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT));
if (wither) { // 120.3d if (wither) { // 120.3d
addCounter(CounterType.get(CounterEnumType.M1M1), damageIn, source.getController(), true, counterTable); addCounter(CounterType.get(CounterEnumType.M1M1), damageIn, source.getController(), null, true, counterTable);
damageType = DamageType.M1M1Counters; damageType = DamageType.M1M1Counters;
} }
else { // 120.3e else { // 120.3e
@@ -6611,7 +6612,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
changed = true; changed = true;
} }
} else { } else {
changed |= addCounter(ct, e.getValue(), e.getRowKey(), true, table) > 0; changed |= addCounter(ct, e.getValue(), e.getRowKey(), null, true, table) > 0;
} }
} }
return changed; return changed;

View File

@@ -1398,7 +1398,7 @@ public class CardFactoryUtil {
inst.addTrigger(triggerDrawn); inst.addTrigger(triggerDrawn);
} else if (keyword.startsWith("Modular")) { } else if (keyword.startsWith("Modular")) {
final String abStr = "DB$ PutCounter | ValidTgts$ Artifact.Creature | " + final String abStr = "DB$ PutCounter | ValidTgts$ Artifact.Creature | " +
"TgtPrompt$ Select target artifact creature | CounterType$ P1P1 | CounterNum$ ModularX"; "TgtPrompt$ Select target artifact creature | CounterType$ P1P1 | CounterNum$ ModularX | Modular$ True";
String trigStr = "Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard" + String trigStr = "Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard" +
" | OptionalDecider$ TriggeredCardController | TriggerController$ TriggeredCardController" + " | OptionalDecider$ TriggeredCardController | TriggerController$ TriggeredCardController" +
@@ -3087,7 +3087,7 @@ public class CardFactoryUtil {
int counters = AbilityUtils.calculateAmount(c, k[1], this); int counters = AbilityUtils.calculateAmount(c, k[1], this);
GameEntityCounterTable table = new GameEntityCounterTable(); GameEntityCounterTable table = new GameEntityCounterTable();
c.addCounter(CounterEnumType.TIME, counters, getActivatingPlayer(), true, table); c.addCounter(CounterEnumType.TIME, counters, getActivatingPlayer(), this, true, table);
table.triggerCountersPutAll(game); table.triggerCountersPutAll(game);
String sb = TextUtil.concatWithSpace(getActivatingPlayer().toString(),"has suspended", c.getName(), "with", String.valueOf(counters),"time counters on it."); String sb = TextUtil.concatWithSpace(getActivatingPlayer().toString(),"has suspended", c.getName(), "with", String.valueOf(counters),"time counters on it.");

View File

@@ -177,7 +177,7 @@ public class CostPutCounter extends CostPartWithList {
@Override @Override
protected Card doPayment(SpellAbility ability, Card targetCard){ protected Card doPayment(SpellAbility ability, Card targetCard){
final Integer i = this.convertAmount(); final Integer i = this.convertAmount();
targetCard.addCounter(this.getCounter(), i, ability.getActivatingPlayer(), ability.getRootAbility().isTrigger(), counterTable); targetCard.addCounter(this.getCounter(), i, ability.getActivatingPlayer(), null, ability.getRootAbility().isTrigger(), counterTable);
return targetCard; return targetCard;
} }

View File

@@ -293,7 +293,7 @@ public class PhaseHandler implements java.io.Serializable {
// all Saga get Lore counter at the begin of pre combat // all Saga get Lore counter at the begin of pre combat
for (Card c : playerTurn.getCardsIn(ZoneType.Battlefield)) { for (Card c : playerTurn.getCardsIn(ZoneType.Battlefield)) {
if (c.getType().hasSubtype("Saga")) { if (c.getType().hasSubtype("Saga")) {
c.addCounter(CounterEnumType.LORE, 1, playerTurn, false, table); c.addCounter(CounterEnumType.LORE, 1, playerTurn, null, false, table);
} }
} }
table.triggerCountersPutAll(game); table.triggerCountersPutAll(game);

View File

@@ -867,12 +867,12 @@ public class Player extends GameEntity implements Comparable<Player> {
return true; return true;
} }
public final int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { public final int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, GameEntityCounterTable table) {
return addCounter(counterType, n, source, applyMultiplier, true, table); return addCounter(counterType, n, source, cause, applyMultiplier, true, table);
} }
@Override @Override
public int addCounter(CounterType counterType, int n, final Player source, boolean applyMultiplier, boolean fireEvents, GameEntityCounterTable table) { public int addCounter(CounterType counterType, int n, final Player source, final SpellAbility cause, boolean applyMultiplier, boolean fireEvents, GameEntityCounterTable table) {
int addAmount = n; int addAmount = n;
if (addAmount <= 0 || !canReceiveCounters(counterType)) { if (addAmount <= 0 || !canReceiveCounters(counterType)) {
// Can't add negative or 0 counters, bail out now // Can't add negative or 0 counters, bail out now
@@ -881,6 +881,7 @@ public class Player extends GameEntity implements Comparable<Player> {
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this); final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
repParams.put(AbilityKey.Source, source); repParams.put(AbilityKey.Source, source);
repParams.put(AbilityKey.Cause, cause);
repParams.put(AbilityKey.CounterType, counterType); repParams.put(AbilityKey.CounterType, counterType);
repParams.put(AbilityKey.CounterNum, addAmount); repParams.put(AbilityKey.CounterNum, addAmount);
repParams.put(AbilityKey.EffectOnly, applyMultiplier); repParams.put(AbilityKey.EffectOnly, applyMultiplier);
@@ -980,7 +981,7 @@ public class Player extends GameEntity implements Comparable<Player> {
} }
public final void addPoisonCounters(final int num, final Card source, GameEntityCounterTable table) { public final void addPoisonCounters(final int num, final Card source, GameEntityCounterTable table) {
int oldPoison = getCounters(CounterEnumType.POISON); int oldPoison = getCounters(CounterEnumType.POISON);
addCounter(CounterEnumType.POISON, num, source.getController(), false, true, table); addCounter(CounterEnumType.POISON, num, source.getController(), null, false, true, table);
if (oldPoison != getCounters(CounterEnumType.POISON)) { if (oldPoison != getCounters(CounterEnumType.POISON)) {
game.fireEvent(new GameEventPlayerPoisoned(this, source, oldPoison, num)); game.fireEvent(new GameEventPlayerPoisoned(this, source, oldPoison, num));

View File

@@ -54,6 +54,10 @@ public class ReplaceAddCounter extends ReplacementEffect {
return false; return false;
} }
if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
return false;
}
if (hasParam("ValidCounterType")) { if (hasParam("ValidCounterType")) {
String type = getParam("ValidCounterType"); String type = getParam("ValidCounterType");
if (CounterType.getType(type) != runParams.get(AbilityKey.CounterType)) { if (CounterType.getType(type) != runParams.get(AbilityKey.CounterType)) {

View File

@@ -218,7 +218,7 @@ public class GameSimulatorTest extends SimulationTestCase {
Game game = initAndCreateGame(); Game game = initAndCreateGame();
Player p = game.getPlayers().get(1); Player p = game.getPlayers().get(1);
Card sorin = addCard("Sorin, Solemn Visitor", p); Card sorin = addCard("Sorin, Solemn Visitor", p);
sorin.addCounter(CounterEnumType.LOYALTY, 5, p, false, null); sorin.addCounter(CounterEnumType.LOYALTY, 5, p, null, false, null);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -262,7 +262,7 @@ public class GameSimulatorTest extends SimulationTestCase {
String bearCardName = "Runeclaw Bear"; String bearCardName = "Runeclaw Bear";
addCard(bearCardName, p); addCard(bearCardName, p);
Card gideon = addCard("Gideon, Ally of Zendikar", p); Card gideon = addCard("Gideon, Ally of Zendikar", p);
gideon.addCounter(CounterEnumType.LOYALTY, 4, p, false, null); gideon.addCounter(CounterEnumType.LOYALTY, 4, p, null, false, null);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -385,7 +385,7 @@ public class GameSimulatorTest extends SimulationTestCase {
Game game = initAndCreateGame(); Game game = initAndCreateGame();
Player p = game.getPlayers().get(1); Player p = game.getPlayers().get(1);
Card sarkhan = addCard(sarkhanCardName, p); Card sarkhan = addCard(sarkhanCardName, p);
sarkhan.addCounter(CounterEnumType.LOYALTY, 4, p, false, null); sarkhan.addCounter(CounterEnumType.LOYALTY, 4, p, null, false, null);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -419,7 +419,7 @@ public class GameSimulatorTest extends SimulationTestCase {
addCard(ornithoperCardName, p); addCard(ornithoperCardName, p);
addCard(bearCardName, p); addCard(bearCardName, p);
Card ajani = addCard(ajaniCardName, p); Card ajani = addCard(ajaniCardName, p);
ajani.addCounter(CounterEnumType.LOYALTY, 4, p, false, null); ajani.addCounter(CounterEnumType.LOYALTY, 4, p, null, false, null);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -450,7 +450,7 @@ public class GameSimulatorTest extends SimulationTestCase {
SpellAbility boltSA = boltCard.getFirstSpellAbility(); SpellAbility boltSA = boltCard.getFirstSpellAbility();
Card ajani = addCard(ajaniCardName, p); Card ajani = addCard(ajaniCardName, p);
ajani.addCounter(CounterEnumType.LOYALTY, 8, p, false, null); ajani.addCounter(CounterEnumType.LOYALTY, 8, p, null, false, null);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -499,7 +499,7 @@ public class GameSimulatorTest extends SimulationTestCase {
addCard("Swamp", p); addCard("Swamp", p);
addCard("Swamp", p); addCard("Swamp", p);
Card depths = addCard("Dark Depths", p); Card depths = addCard("Dark Depths", p);
depths.addCounter(CounterEnumType.ICE, 10, p, false, null); depths.addCounter(CounterEnumType.ICE, 10, p, null, false, null);
Card thespian = addCard("Thespian's Stage", p); Card thespian = addCard("Thespian's Stage", p);
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
@@ -2176,7 +2176,7 @@ public class GameSimulatorTest extends SimulationTestCase {
Player p = game.getPlayers().get(0); Player p = game.getPlayers().get(0);
Card polukranos = addCard(polukranosCardName, p); Card polukranos = addCard(polukranosCardName, p);
polukranos.addCounter(CounterEnumType.P1P1, 6, p, false, null); polukranos.addCounter(CounterEnumType.P1P1, 6, p, null, false, null);
addCard(hydraCardName, p); addCard(hydraCardName, p);
addCard(leylineCardName, p); addCard(leylineCardName, p);
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
@@ -2220,7 +2220,7 @@ public class GameSimulatorTest extends SimulationTestCase {
} }
Card nishoba = addCard(nishobaName, p1); Card nishoba = addCard(nishobaName, p1);
nishoba.addCounter(CounterEnumType.P1P1, 7, p1, false, null); nishoba.addCounter(CounterEnumType.P1P1, 7, p1, null, false, null);
addCard(capridorName, p1); addCard(capridorName, p1);
Card pridemate = addCard(pridemateName, p1); Card pridemate = addCard(pridemateName, p1);
Card indestructibility = addCard(indestructibilityName, p1); Card indestructibility = addCard(indestructibilityName, p1);

View File

@@ -0,0 +1,11 @@
Name:Zabaz, the Glimmerwasp
ManaCost:1
Types:Legendary Artifact Creature Insect
PT:0/0
K:Modular:1
R:Event$ AddCounter | ActiveZones$ Battlefield | ValidCause$ Triggered.Modular | ValidCard$ Creature.YouCtrl | ValidCounterType$ P1P1 | ReplaceWith$ AddOneMoreCounter | Description$ If a modular triggered ability would put one or more +1/+1 counters on a creature you control, that many plus one +1/+1 counters are put on it instead.
SVar:AddOneMoreCounter:DB$ ReplaceEffect | VarName$ CounterNum | VarValue$ X
SVar:X:ReplaceCount$CounterNum/Plus.1
A:AB$ Destroy | Cost$ R | ValidTgts$ Artifact.YouCtrl | TgtPrompt$ Choose target artifact you control | SpellDescription$ Destroy target artifact you control.
A:AB$ Pump | Cost$ W | KW$ Flying | Defined$ Self | SpellDescription$ CARDNAME gains flying until end of turn.
Oracle:Modular 1\nIf a modular triggered ability would put one or more +1/+1 counters on a creature you control, that many plus one +1/+1 counters are put on it instead.\n{R}: Destroy target artifact you control.\n{W}: Zabaz, the Glimmerwasp gains flying until end of turn.

View File

@@ -2431,7 +2431,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (subtract) { if (subtract) {
card.subtractCounter(counter, count); card.subtractCounter(counter, count);
} else { } else {
card.addCounter(counter, count, card.getController(), false, null); card.addCounter(counter, count, card.getController(), null, false, null);
} }
} }