From fc82dbb9aa9bb95a182992b794e727fc8c7cd290 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 11 Jun 2021 08:31:21 +0200 Subject: [PATCH] Zabaz: add Cause to ReplaceAddCounter --- .../main/java/forge/ai/ComputerUtilCard.java | 2 +- .../src/main/java/forge/ai/GameState.java | 2 +- .../src/main/java/forge/ai/SpecialCardAi.java | 2 +- .../src/main/java/forge/game/ForgeScript.java | 2 ++ .../src/main/java/forge/game/GameAction.java | 2 +- .../src/main/java/forge/game/GameEntity.java | 6 ++--- .../game/ability/effects/AmassEffect.java | 2 +- .../ability/effects/ChangeZoneEffect.java | 2 +- .../ability/effects/CountersMoveEffect.java | 6 ++--- .../effects/CountersMultiplyEffect.java | 4 ++-- .../ability/effects/CountersNoteEffect.java | 6 ++--- .../effects/CountersProliferateEffect.java | 2 +- .../ability/effects/CountersPutAllEffect.java | 2 +- .../ability/effects/CountersPutEffect.java | 12 +++++----- .../effects/CountersPutOrRemoveEffect.java | 2 +- .../forge/game/ability/effects/DigEffect.java | 4 ++-- .../game/ability/effects/ExploreEffect.java | 2 +- .../game/ability/effects/SacrificeEffect.java | 2 +- .../game/ability/effects/SetStateEffect.java | 2 +- .../src/main/java/forge/game/card/Card.java | 23 ++++++++++--------- .../java/forge/game/card/CardFactoryUtil.java | 4 ++-- .../java/forge/game/cost/CostPutCounter.java | 2 +- .../java/forge/game/phase/PhaseHandler.java | 2 +- .../main/java/forge/game/player/Player.java | 9 ++++---- .../game/replacement/ReplaceAddCounter.java | 4 ++++ .../ai/simulation/GameSimulatorTest.java | 16 ++++++------- .../cardsfolder/z/zabaz_the_glimmerwasp.txt | 11 +++++++++ .../forge/player/PlayerControllerHuman.java | 2 +- 28 files changed, 78 insertions(+), 59 deletions(-) create mode 100644 forge-gui/res/cardsfolder/z/zabaz_the_glimmerwasp.txt diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index b710879376f..039745fc1cd 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -1630,7 +1630,7 @@ public class ComputerUtilCard { pumped.addChangedCardKeywords(kws, null, false, false, timestamp); Set types = c.getCounters().keySet(); 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.) if (c.isTapped()) { diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 40ea465041a..19c9bee363e 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -1175,7 +1175,7 @@ public abstract class GameState { String[] allCounterStrings = counterString.split(","); for (final String counterPair : allCounterStrings) { 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); } } diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index dcb194d663e..501a3ab4a61 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -217,7 +217,7 @@ public class SpecialCardAi { Card animated = AnimateAi.becomeAnimated(sa.getHostCard(), sa.getSubAbility()); 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 isValuableAttacker = ph.is(PhaseType.MAIN1, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated); diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index 356b41acf38..bdf433a80e4 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -155,6 +155,8 @@ public class ForgeScript { return sa.isAftermath(); } else if (property.equals("MorphUp")) { return sa.isMorphUp(); + } else if (property.equals("Modular")) { + return sa.hasParam("Modular"); } else if (property.equals("Equip")) { return sa.hasParam("Equip"); } else if (property.equals("Boast")) { diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index b916a1b721e..f3a9dd68e7f 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1235,7 +1235,7 @@ public class GameAction { int loyal = c.getCounters(CounterEnumType.LOYALTY); if (loyal < beeble) { 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); } else if (loyal > beeble) { c.subtractCounter(CounterEnumType.LOYALTY, loyal - beeble); diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index ba4a2f26498..06610ed59b3 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -300,7 +300,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { abstract public void setCounters(final Map allCounters); 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 clearCounters(); @@ -308,8 +308,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { 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) { - return addCounter(CounterType.get(counterType), n, source, applyMultiplier, fireEvents, 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, cause, applyMultiplier, fireEvents, table); } public void subtractCounter(final CounterEnumType counterName, final int n) { subtractCounter(CounterType.get(counterName), n); diff --git a/forge-game/src/main/java/forge/game/ability/effects/AmassEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AmassEffect.java index 9800cc32764..fe4bc675585 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AmassEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AmassEffect.java @@ -93,7 +93,7 @@ public class AmassEffect extends TokenEffectBase { GameEntityCounterTable table = new GameEntityCounterTable(); 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); if (remember) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 7d2d07e1985..5e903cfbc13 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -709,7 +709,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); 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")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java index 9a20378f42e..d636a43cdbd 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java @@ -163,7 +163,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { } } for (Map.Entry 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); @@ -225,7 +225,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { if (cnum > 0) { source.subtractCounter(cType, cnum); - cur.addCounter(cType, cnum, player, true, table); + cur.addCounter(cType, cnum, player, sa, true, table); game.updateLastStateForCard(cur); updateSource = true; } @@ -311,7 +311,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { } for (Map.Entry 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); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java index 84c1a609ab6..8f7cd9f9653 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java @@ -54,10 +54,10 @@ public class CountersMultiplyEffect extends SpellAbilityEffect { continue; } 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 { for (Map.Entry 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); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java index b2705b69516..b1cbf040fe7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java @@ -30,7 +30,7 @@ public class CountersNoteEffect extends SpellAbilityEffect { if (mode.equals(MODE_STORE)) { noteCounters(c, source); } else if (mode.equals(MODE_LOAD)) { - loadCounters(c, source, p, table); + loadCounters(c, source, p, sa, table); } } 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 svar : source.getSVars().entrySet()) { String key = svar.getKey(); if (key.startsWith(NOTE_COUNTERS)) { notee.addCounter( 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 } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java index 0ae32240416..22ed2be4fdc 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java @@ -48,7 +48,7 @@ public class CountersProliferateEffect extends SpellAbilityEffect { GameEntityCounterTable table = new GameEntityCounterTable(); for (final GameEntity ge : result) { 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) { Card c = (Card) ge; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java index fe8fd590385..d80af630170 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java @@ -71,7 +71,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect { if (etbcounter) { tgtCard.addEtbCounter(CounterType.getType(type), counterAmount, placer); } else { - tgtCard.addCounter(CounterType.getType(type), counterAmount, placer, inBattlefield, table); + tgtCard.addCounter(CounterType.getType(type), counterAmount, placer, sa, inBattlefield, table); } game.updateLastStateForCard(tgtCard); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index f5b35b965d9..cd5dbe0c895 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -226,10 +226,10 @@ public class CountersPutEffect extends SpellAbilityEffect { if (eachExistingCounter) { for (CounterType ct : choices) { 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) { - gameCard.addCounter(ct, counterAmount, placer, true, table); + gameCard.addCounter(ct, counterAmount, placer, sa, true, table); } } continue; @@ -253,7 +253,7 @@ public class CountersPutEffect extends SpellAbilityEffect { for (Card c : AbilityUtils.getDefinedCards(card, sa.getParam("EachFromSource"), sa)) { for (Entry cti : c.getCounters().entrySet()) { 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) { gameCard.addEtbCounter(counterType, counterAmount, placer); } else { - int addedAmount = gameCard.addCounter(counterType, counterAmount, placer, true, table); + int addedAmount = gameCard.addCounter(counterType, counterAmount, placer, sa, true, table); if (addedAmount > 0) { counterAdded = true; } @@ -372,7 +372,7 @@ public class CountersPutEffect extends SpellAbilityEffect { if (etbcounter) { gameCard.addEtbCounter(counterType, counterAmount, placer); } else { - if (gameCard.addCounter(counterType, counterAmount, placer, false, table) > 0) { + if (gameCard.addCounter(counterType, counterAmount, placer, sa, false, table) > 0) { counterAdded = true; } } @@ -388,7 +388,7 @@ public class CountersPutEffect extends SpellAbilityEffect { } else if (obj instanceof Player) { // Add Counters to players! Player pl = (Player) obj; - pl.addCounter(counterType, counterAmount, placer, true, table); + pl.addCounter(counterType, counterAmount, placer, sa, true, table); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java index 7490946e2c9..2c535de9099 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java @@ -111,7 +111,7 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect { 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 { tgtCard.subtractCounter(chosenType, counterAmount); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 467fd6d72af..ad67308edc1 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -336,7 +336,7 @@ public class DigEffect extends SpellAbilityEffect { } else if (destZone1.equals(ZoneType.Exile)) { if (sa.hasParam("ExileWithCounter")) { c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), - 1, player, true, counterTable); + 1, player, sa, true, counterTable); } c.setExiledWith(effectHost); c.setExiledBy(effectHost.getController()); @@ -408,7 +408,7 @@ public class DigEffect extends SpellAbilityEffect { if (destZone2 == ZoneType.Exile) { if (sa.hasParam("ExileWithCounter")) { c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), - 1, player, true, counterTable); + 1, player, sa, true, counterTable); } c.setExiledWith(effectHost); c.setExiledBy(effectHost.getController()); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java index 8a3985aeb55..b820370714a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java @@ -83,7 +83,7 @@ public class ExploreEffect extends SpellAbilityEffect { // if the card is not more in the game anymore // this might still return true but its no problem 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); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java index 197509ff0dd..8418c8db7d8 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java @@ -55,7 +55,7 @@ public class SacrificeEffect extends SpellAbilityEffect { } } else if (sa.hasParam("CumulativeUpkeep")) { GameEntityCounterTable table = new GameEntityCounterTable(); - card.addCounter(CounterEnumType.AGE, 1, activator, true, table); + card.addCounter(CounterEnumType.AGE, 1, activator, sa, true, table); table.triggerCountersPutAll(game); diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 1989de4d3df..aff51d34bbb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -160,7 +160,7 @@ public class SetStateEffect extends SpellAbilityEffect { } game.fireEvent(new GameEventCardStatsChanged(gameCard)); if (sa.hasParam("Mega")) { - gameCard.addCounter(CounterEnumType.P1P1, 1, p, true, table); + gameCard.addCounter(CounterEnumType.P1P1, 1, p, sa, true, table); } if (remChanged) { host.addRemembered(gameCard); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 0c8cccc9be1..bbd89b43d26 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1382,21 +1382,21 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return true; } - public final int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { - return addCounter(counterType, n, source, applyMultiplier, true, 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, cause, applyMultiplier, true, table); } - public final int addCounterFireNoEvents(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { - return addCounter(counterType, n, source, applyMultiplier, false, 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, cause, applyMultiplier, false, table); } - public final int addCounter(final CounterEnumType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { - return addCounter(counterType, n, source, applyMultiplier, true, 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, cause, applyMultiplier, true, table); } - public final int addCounterFireNoEvents(final CounterEnumType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { - return addCounter(counterType, n, source, applyMultiplier, false, 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, cause, applyMultiplier, false, table); } @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; if(addAmount <= 0 || !canReceiveCounters(counterType)) { // As per rule 107.1b @@ -1404,6 +1404,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } final Map repParams = AbilityKey.mapFromAffected(this); repParams.put(AbilityKey.Source, source); + repParams.put(AbilityKey.Cause, cause); repParams.put(AbilityKey.CounterType, counterType); repParams.put(AbilityKey.CounterNum, addAmount); repParams.put(AbilityKey.EffectOnly, applyMultiplier); @@ -5273,7 +5274,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT)); 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; } else { // 120.3e @@ -6611,7 +6612,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { changed = true; } } else { - changed |= addCounter(ct, e.getValue(), e.getRowKey(), true, table) > 0; + changed |= addCounter(ct, e.getValue(), e.getRowKey(), null, true, table) > 0; } } return changed; diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index f1aaeaae705..29dd3fb5da7 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1398,7 +1398,7 @@ public class CardFactoryUtil { inst.addTrigger(triggerDrawn); } else if (keyword.startsWith("Modular")) { 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" + " | OptionalDecider$ TriggeredCardController | TriggerController$ TriggeredCardController" + @@ -3087,7 +3087,7 @@ public class CardFactoryUtil { int counters = AbilityUtils.calculateAmount(c, k[1], this); GameEntityCounterTable table = new GameEntityCounterTable(); - c.addCounter(CounterEnumType.TIME, counters, getActivatingPlayer(), true, table); + c.addCounter(CounterEnumType.TIME, counters, getActivatingPlayer(), this, true, table); table.triggerCountersPutAll(game); String sb = TextUtil.concatWithSpace(getActivatingPlayer().toString(),"has suspended", c.getName(), "with", String.valueOf(counters),"time counters on it."); diff --git a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java index 914db9d175e..f6f58c8894e 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java @@ -177,7 +177,7 @@ public class CostPutCounter extends CostPartWithList { @Override protected Card doPayment(SpellAbility ability, Card targetCard){ 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; } diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 9974a79bebf..2f0199a2499 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -293,7 +293,7 @@ public class PhaseHandler implements java.io.Serializable { // all Saga get Lore counter at the begin of pre combat for (Card c : playerTurn.getCardsIn(ZoneType.Battlefield)) { 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); diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index ab5c18ae274..b8ad6e0576f 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -867,12 +867,12 @@ public class Player extends GameEntity implements Comparable { return true; } - public final int addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, GameEntityCounterTable table) { - return addCounter(counterType, n, source, applyMultiplier, true, 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, cause, applyMultiplier, true, table); } @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; if (addAmount <= 0 || !canReceiveCounters(counterType)) { // Can't add negative or 0 counters, bail out now @@ -881,6 +881,7 @@ public class Player extends GameEntity implements Comparable { final Map repParams = AbilityKey.mapFromAffected(this); repParams.put(AbilityKey.Source, source); + repParams.put(AbilityKey.Cause, cause); repParams.put(AbilityKey.CounterType, counterType); repParams.put(AbilityKey.CounterNum, addAmount); repParams.put(AbilityKey.EffectOnly, applyMultiplier); @@ -980,7 +981,7 @@ public class Player extends GameEntity implements Comparable { } public final void addPoisonCounters(final int num, final Card source, GameEntityCounterTable table) { 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)) { game.fireEvent(new GameEventPlayerPoisoned(this, source, oldPoison, num)); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java index 3721aa0e7d9..f3dfdfd8bf9 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java @@ -54,6 +54,10 @@ public class ReplaceAddCounter extends ReplacementEffect { return false; } + if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) { + return false; + } + if (hasParam("ValidCounterType")) { String type = getParam("ValidCounterType"); if (CounterType.getType(type) != runParams.get(AbilityKey.CounterType)) { diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java index 7ec016eb0fe..6ac6cba7903 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java @@ -218,7 +218,7 @@ public class GameSimulatorTest extends SimulationTestCase { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); 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.getAction().checkStateEffects(true); @@ -262,7 +262,7 @@ public class GameSimulatorTest extends SimulationTestCase { String bearCardName = "Runeclaw Bear"; addCard(bearCardName, 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.getAction().checkStateEffects(true); @@ -385,7 +385,7 @@ public class GameSimulatorTest extends SimulationTestCase { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); 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.getAction().checkStateEffects(true); @@ -419,7 +419,7 @@ public class GameSimulatorTest extends SimulationTestCase { addCard(ornithoperCardName, p); addCard(bearCardName, 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.getAction().checkStateEffects(true); @@ -450,7 +450,7 @@ public class GameSimulatorTest extends SimulationTestCase { SpellAbility boltSA = boltCard.getFirstSpellAbility(); 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.getAction().checkStateEffects(true); @@ -499,7 +499,7 @@ public class GameSimulatorTest extends SimulationTestCase { addCard("Swamp", p); addCard("Swamp", 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); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -2176,7 +2176,7 @@ public class GameSimulatorTest extends SimulationTestCase { Player p = game.getPlayers().get(0); 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(leylineCardName, p); for (int i = 0; i < 2; ++i) { @@ -2220,7 +2220,7 @@ public class GameSimulatorTest extends SimulationTestCase { } 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); Card pridemate = addCard(pridemateName, p1); Card indestructibility = addCard(indestructibilityName, p1); diff --git a/forge-gui/res/cardsfolder/z/zabaz_the_glimmerwasp.txt b/forge-gui/res/cardsfolder/z/zabaz_the_glimmerwasp.txt new file mode 100644 index 00000000000..085d1f1039d --- /dev/null +++ b/forge-gui/res/cardsfolder/z/zabaz_the_glimmerwasp.txt @@ -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. diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 2eea93c1e7b..6acb6261bda 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2431,7 +2431,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (subtract) { card.subtractCounter(counter, count); } else { - card.addCounter(counter, count, card.getController(), false, null); + card.addCounter(counter, count, card.getController(), null, false, null); } }