diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersRemoveEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersRemoveEffect.java index 4d73671c8ef..f8142b029fd 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersRemoveEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersRemoveEffect.java @@ -4,6 +4,8 @@ import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; +import forge.game.card.CardCollectionView; +import forge.game.card.CardLists; import forge.game.card.CounterType; import forge.game.player.Player; import forge.game.player.PlayerController; @@ -69,11 +71,14 @@ public class CountersRemoveEffect extends SpellAbilityEffect { final Card card = sa.getHostCard(); final Game game = card.getGame(); + final Player player = sa.getActivatingPlayer(); + + PlayerController pc = player.getController(); final String type = sa.getParam("CounterType"); final String num = sa.getParam("CounterNum"); int cntToRemove = 0; - if (!num.equals("All") && !num.equals("Remembered")) { + if (!num.equals("All") && !num.equals("Any") && !num.equals("Remembered")) { cntToRemove = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa); } @@ -96,6 +101,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect { } boolean rememberRemoved = sa.hasParam("RememberRemoved"); + boolean rememberAmount = sa.hasParam("RememberAmount"); for (final Player tgtPlayer : getTargetPlayers(sa)) { // Removing energy @@ -107,7 +113,23 @@ public class CountersRemoveEffect extends SpellAbilityEffect { } } - for (final Card tgtCard : getTargetCards(sa)) { + CardCollectionView srcCards = null; + if (sa.hasParam("ValidSource")) { + srcCards = game.getCardsIn(ZoneType.Battlefield); + srcCards = CardLists.getValidCards(srcCards, sa.getParam("ValidSource"), player, card, sa); + if (num.equals("Any")) { + StringBuilder sb = new StringBuilder(); + sb.append("Choose cards to take ").append(counterType.getName()).append(" counters from"); + + srcCards = player.getController().chooseCardsForEffect(srcCards, sa, sb.toString(), 0, srcCards.size(), true); + } + } else { + srcCards = getTargetCards(sa); + } + + int totalRemoved = 0; + + for (final Card tgtCard : srcCards) { Card gameCard = game.getCardState(tgtCard, null); // gameCard is LKI in that case, the card is not in game anymore // or the timestamp did change @@ -123,14 +145,12 @@ public class CountersRemoveEffect extends SpellAbilityEffect { } game.updateLastStateForCard(gameCard); continue; - } else if (num.equals("All")) { + } else if (num.equals("All") || num.equals("Any")) { cntToRemove = gameCard.getCounters(counterType); - } else if (sa.getParam("CounterNum").equals("Remembered")) { + } else if (num.equals("Remembered")) { cntToRemove = gameCard.getCountersAddedBy(card, counterType); } - - PlayerController pc = sa.getActivatingPlayer().getController(); - + if (type.equals("Any")) { while (cntToRemove > 0 && gameCard.hasCounters()) { final Map tgtCounters = gameCard.getCounters(); @@ -162,7 +182,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect { cntToRemove = Math.min(cntToRemove, gameCard.getCounters(counterType)); if (zone.is(ZoneType.Battlefield) || zone.is(ZoneType.Exile)) { - if (sa.hasParam("UpTo")) { + if (sa.hasParam("UpTo") || num.equals("Any")) { Map params = Maps.newHashMap(); params.put("Target", gameCard); params.put("CounterType", type); @@ -179,10 +199,17 @@ public class CountersRemoveEffect extends SpellAbilityEffect { } } game.updateLastStateForCard(gameCard); + + totalRemoved += cntToRemove; } } } } + + if (totalRemoved > 0 && rememberAmount) { + // TODO use SpellAbility Remember later + card.addRemembered(Integer.valueOf(totalRemoved)); + } } } diff --git a/forge-gui/res/cardsfolder/p/protean_raider.txt b/forge-gui/res/cardsfolder/p/protean_raider.txt index 8426dc32a39..dc40c46a1a5 100644 --- a/forge-gui/res/cardsfolder/p/protean_raider.txt +++ b/forge-gui/res/cardsfolder/p/protean_raider.txt @@ -2,7 +2,7 @@ Name:Protean Raider ManaCost:1 U R Types:Creature Shapeshifter Pirate PT:2/2 -R:Event$ Moved | Destination$ Battlefield | ValidCard$ Card.Self | Layer$ Clone | Optional$ True | ReplaceWith$ DBCopy | CheckSVar$ RaidTest | References$ RaidTest | Description$ Raid — If you attacked with a creature this turn, you may have CARDNAME enter the battlefield as a copy of any creature on the battlefield. +R:Event$ Moved | Destination$ Battlefield | ValidCard$ Card.Self | Layer$ Copy | Optional$ True | ReplaceWith$ DBCopy | CheckSVar$ RaidTest | References$ RaidTest | Description$ Raid — If you attacked with a creature this turn, you may have CARDNAME enter the battlefield as a copy of any creature on the battlefield. SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | SubAbility$ DBChangeZone | SpellDescription$ Raid — If you attacked with a creature this turn, you may have CARDNAME enter the battlefield as a copy of any creature on the battlefield. SVar:DBChangeZone:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard SVar:RaidTest:Count$AttackersDeclared diff --git a/forge-gui/res/cardsfolder/upcoming/galloping_lizrog.txt b/forge-gui/res/cardsfolder/upcoming/galloping_lizrog.txt new file mode 100644 index 00000000000..5ad3b047aeb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/galloping_lizrog.txt @@ -0,0 +1,11 @@ +Name:Galloping Lizrog +ManaCost:3 G U +Types:Creature Frog Lizard +PT:3/3 +K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ TrigRemoveCounters | TriggerDescription$ When CARDNAME enters the battlefield, you may remove any number of +1/+1 counters from among creatures you control. If you do, put twice that many +1/+1 counters on CARDNAME. +SVar:TrigRemoveCounters:DB$ RemoveCounter | ValidSource$ Creature.YouCtrl+counters_GE1_P1P1 | CounterType$ P1P1 | CounterNum$ Any | SubAbility$ DBPutCounters | RememberAmount$ True | StackDescription$ You may remove any number of +1/+1 counters from among creatures you control. +SVar:DBPutCounters:DB$PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | CounterNum$ X | References$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$RememberedNumber/Twice +Oracle:Trample\nWhen Galloping Lizrog enters the battlefield, you may remove any number of +1/+1 counters from among creatures you control. If you do, put twice that many +1/+1 counters on Galloping Lizrog. diff --git a/forge-gui/res/puzzle/PS_CFB.pzl b/forge-gui/res/puzzle/PS_CFB.pzl new file mode 100644 index 00000000000..5735ee3f375 --- /dev/null +++ b/forge-gui/res/puzzle/PS_CFB.pzl @@ -0,0 +1,16 @@ +[metadata] +Name:Possibility Storm - How Much Fireball Can You Channel? +URL:http://www.possibilitystorm.com/wp-content/uploads/2019/01/095.-CFB001-1.jpg +Goal:Win +Turns:1 +Difficulty:Special +Description:Start at the beginning of your first main phase, and use the classic Channel + Fireball combo to inflict as much damage as possible! Your opponent has named Aetherflux Reservoir for his Sorcerous Spyglass. +[state] +humanlife=1 +ailife=1 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Rewind;Snapcaster Mage;High Tide;Channel;Fireball;Baral's Expertise;Walking Ballista;Snap +humanbattlefield=Man-o'-War;Beamsplitter Mage;Aetherflux Reservoir;Breeding Pool;Breeding Pool;Breeding Pool;Breeding Pool;Steam Vents;Steam Vents;Steam Vents;Steam Vents +aibattlefield=Sorcerous Spyglass|NamedCard:Aetherflux Reservoir;Emrakul, the Aeons Torn;Kozilek, Butcher of Truth;Ulamog, the Infinite Gyre