From 2165a45a1ff580cda599c34db274fbf0c3322501 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 8 Apr 2023 10:46:45 +0200 Subject: [PATCH 1/5] CounterAddedOnce add FirstTime --- forge-game/src/main/java/forge/game/Game.java | 14 ++++++++++++++ forge-game/src/main/java/forge/game/card/Card.java | 2 ++ .../game/trigger/TriggerCounterAddedOnce.java | 6 ++++++ .../res/cardsfolder/upcoming/axgard_artisan.txt | 7 +++++++ .../res/cardsfolder/upcoming/botanical_brawler.txt | 9 +++++++++ 5 files changed, 38 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 461768656ee..509553c44ff 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -1132,6 +1132,20 @@ public class Game { } return result; } + public int getCounterAddedThisTurn(CounterType cType, Card card) { + int result = 0; + if (!countersAddedThisTurn.containsRow(cType)) { + return result; + } + for (List> l : countersAddedThisTurn.row(cType).values()) { + for (Pair p : l) { + if (p.getKey().equalsWithTimestamp(card)) { + result += p.getValue(); + } + } + } + return result; + } public void clearCounterAddedThisTurn() { countersAddedThisTurn.clear(); 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 0179aeb57d9..f50852853bf 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1447,6 +1447,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { final int toughnessBonusBefore = getToughnessBonusFromCounters(); final int loyaltyBefore = getCurrentLoyalty(); + int addedThisTurn = getGame().getCounterAddedThisTurn(counterType, this); setCounters(counterType, newValue); getGame().addCounterAddedThisTurn(source, counterType, this, addAmount); view.updateCounters(this); @@ -1473,6 +1474,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } if (addAmount > 0) { runParams.put(AbilityKey.CounterAmount, addAmount); + runParams.put(AbilityKey.FirstTime, addedThisTurn == 0); getGame().getTriggerHandler().runTrigger( TriggerType.CounterAddedOnce, AbilityKey.newMap(runParams), false); } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java index 6c24647ad06..bc0453ae592 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java @@ -55,6 +55,12 @@ public class TriggerCounterAddedOnce extends Trigger { * @param runParams*/ @Override public final boolean performTest(final Map runParams) { + if (hasParam("FirstTime")) { + if (!(boolean) runParams.get(AbilityKey.FirstTime)) { + return false; + } + } + if (hasParam("CounterType")) { final CounterType addedType = (CounterType) runParams.get(AbilityKey.CounterType); final String type = getParam("CounterType"); diff --git a/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt b/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt new file mode 100644 index 00000000000..146dccee503 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt @@ -0,0 +1,7 @@ +Name:Axgard Artisan +ManaCost:1 R +Types:Creature Dwarf Artificer +PT:2/1 +T:Mode$ CounterAddedOnce | ValidCard$ Card.Self | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigToken | TriggerDescription$ Whenever one or more +1/+1 counters are put on CARDNAME for the first time each turn, create a Treasure token. (it’s an artifact with “{T}, Sacrifice this artifact: Add one mana of any color.”) +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | TokenOwner$ You +Oracle:Whenever one or more +1/+1 counters are put on Axgard Artisan for the first time each turn, create a Treasure token. (it’s an artifact with “{T}, Sacrifice this artifact: Add one mana of any color.”) diff --git a/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt new file mode 100644 index 00000000000..b64c8f4abe6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt @@ -0,0 +1,9 @@ +Name:Botanical Brawler +ManaCost:G W +Types:Creature Elemental Warrior +PT:0/0 +K:Trample +K:etbCounter:P1P1:2 +T:Mode$ CounterAddedOnce | ValidCard$ Card.Other+inZoneBattlefield | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 +Oracle:Trample\nBotanical Brawler enters the battlefield with two +1/+1 counters on it.\nWhenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on Botanical Brawler. From 2a64cfa7032fe5640f1984cfae07ccfcce5bcdcf Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 8 Apr 2023 10:51:46 +0200 Subject: [PATCH 2/5] Update botanical_brawler.txt --- forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt index b64c8f4abe6..4023e59101b 100644 --- a/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt +++ b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt @@ -4,6 +4,6 @@ Types:Creature Elemental Warrior PT:0/0 K:Trample K:etbCounter:P1P1:2 -T:Mode$ CounterAddedOnce | ValidCard$ Card.Other+inZoneBattlefield | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on CARDNAME. +T:Mode$ CounterAddedOnce | ValidCard$ Card.Other+YouCtrl+inZoneBattlefield | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 Oracle:Trample\nBotanical Brawler enters the battlefield with two +1/+1 counters on it.\nWhenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on Botanical Brawler. From e1fc48504f3706c18866c812afb478ea9db1a380 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 8 Apr 2023 11:25:19 +0200 Subject: [PATCH 3/5] DeckHints --- forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt | 1 + forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt b/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt index 146dccee503..7b22c469db9 100644 --- a/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt +++ b/forge-gui/res/cardsfolder/upcoming/axgard_artisan.txt @@ -4,4 +4,5 @@ Types:Creature Dwarf Artificer PT:2/1 T:Mode$ CounterAddedOnce | ValidCard$ Card.Self | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigToken | TriggerDescription$ Whenever one or more +1/+1 counters are put on CARDNAME for the first time each turn, create a Treasure token. (it’s an artifact with “{T}, Sacrifice this artifact: Add one mana of any color.”) SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | TokenOwner$ You +DeckHints:Ability$Counters Oracle:Whenever one or more +1/+1 counters are put on Axgard Artisan for the first time each turn, create a Treasure token. (it’s an artifact with “{T}, Sacrifice this artifact: Add one mana of any color.”) diff --git a/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt index 4023e59101b..a6844f4f4fd 100644 --- a/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt +++ b/forge-gui/res/cardsfolder/upcoming/botanical_brawler.txt @@ -6,4 +6,6 @@ K:Trample K:etbCounter:P1P1:2 T:Mode$ CounterAddedOnce | ValidCard$ Card.Other+YouCtrl+inZoneBattlefield | TriggerZones$ Battlefield | CounterType$ P1P1 | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters +DeckHints:Ability$Counters Oracle:Trample\nBotanical Brawler enters the battlefield with two +1/+1 counters on it.\nWhenever one or more +1/+1 counters are put on another permanent you control, if it’s the first time +1/+1 counters have been put on that permanent this turn, put a +1/+1 counter on Botanical Brawler. From 7e976f8908b944d8a46eda0bf3dd0831764723fa Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 8 Apr 2023 12:19:27 +0200 Subject: [PATCH 4/5] remove ChangeZoneEffect setting timestamp --- .../java/forge/game/ability/effects/ChangeZoneEffect.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) 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 5151cba7bd9..70ff97a4444 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 @@ -505,7 +505,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final boolean optional = sa.hasParam("Optional"); final boolean shuffle = sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle")); - final long ts = game.getNextTimestamp(); boolean combatChanged = false; Player chooser = player; @@ -703,11 +702,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { combatChanged = true; } - movedCard.setTimestamp(ts); if (movedCard.isInPlay()) { // need to also update LKI List lki = movedCard.getZone().getCardsAddedThisTurn(null); - lki.get(lki.lastIndexOf(movedCard)).setTimestamp(ts); + lki.get(lki.lastIndexOf(movedCard)).setTimestamp(movedCard.getTimestamp()); } if (sa.hasParam("AttachAfter") && movedCard.isAttachment()) { @@ -1284,7 +1282,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { List origin = HiddenOriginChoicesMap.get(player).origin; ZoneType destination = HiddenOriginChoicesMap.get(player).destination; CardCollection movedCards = new CardCollection(); - long ts = game.getNextTimestamp(); Player decider = ObjectUtils.firstNonNull(chooser, player); for (final Card c : chosenCards) { @@ -1391,11 +1388,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } movedCard = game.getAction().moveToPlay(c, c.getController(), sa, moveParams); - movedCard.setTimestamp(ts); if (movedCard.isInPlay()) { // need to also update LKI List lki = movedCard.getZone().getCardsAddedThisTurn(null); - lki.get(lki.lastIndexOf(movedCard)).setTimestamp(ts); + lki.get(lki.lastIndexOf(movedCard)).setTimestamp(movedCard.getTimestamp()); } if (sa.hasParam("AttachAfter") && movedCard.isAttachment() && movedCard.isInPlay()) { From a5ac77a5c4ae87697420873091ef3c03287cf6e3 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sat, 8 Apr 2023 13:09:03 +0200 Subject: [PATCH 5/5] remove more lines --- .../forge/game/ability/effects/ChangeZoneEffect.java | 12 ------------ 1 file changed, 12 deletions(-) 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 70ff97a4444..212bd6cbbf0 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 @@ -702,12 +702,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { combatChanged = true; } - if (movedCard.isInPlay()) { - // need to also update LKI - List lki = movedCard.getZone().getCardsAddedThisTurn(null); - lki.get(lki.lastIndexOf(movedCard)).setTimestamp(movedCard.getTimestamp()); - } - if (sa.hasParam("AttachAfter") && movedCard.isAttachment()) { CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachAfter"), sa); if (list.isEmpty()) { @@ -1388,12 +1382,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } movedCard = game.getAction().moveToPlay(c, c.getController(), sa, moveParams); - if (movedCard.isInPlay()) { - // need to also update LKI - List lki = movedCard.getZone().getCardsAddedThisTurn(null); - lki.get(lki.lastIndexOf(movedCard)).setTimestamp(movedCard.getTimestamp()); - } - if (sa.hasParam("AttachAfter") && movedCard.isAttachment() && movedCard.isInPlay()) { CardCollection list = AbilityUtils.getDefinedCards(source, sa.getParam("AttachAfter"), sa); if (list.isEmpty()) {