From 2e9eb7fb330d881b6903e2784f96661da58bf9a5 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Mon, 19 Jun 2023 19:15:48 -0400 Subject: [PATCH] [LTC] Implement Trap the Trespassers --- .../src/mage/cards/c/CirdanTheShipwright.java | 4 + .../src/mage/cards/t/TrapTheTrespassers.java | 118 ++++++++++++++++++ .../sets/TalesOfMiddleEarthCommander.java | 1 + .../main/java/mage/choices/VoteHandler.java | 6 +- 4 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TrapTheTrespassers.java diff --git a/Mage.Sets/src/mage/cards/c/CirdanTheShipwright.java b/Mage.Sets/src/mage/cards/c/CirdanTheShipwright.java index 5aaf7a8a861..004974b57e9 100644 --- a/Mage.Sets/src/mage/cards/c/CirdanTheShipwright.java +++ b/Mage.Sets/src/mage/cards/c/CirdanTheShipwright.java @@ -103,6 +103,10 @@ class CirdanTheShipwrightEffect extends OneShotEffect { class CirdanTheShipwrightVote extends VoteHandler { + CirdanTheShipwrightVote() { + this.secret = true; + } + @Override protected Set getPossibleVotes(Ability source, Game game) { return game diff --git a/Mage.Sets/src/mage/cards/t/TrapTheTrespassers.java b/Mage.Sets/src/mage/cards/t/TrapTheTrespassers.java new file mode 100644 index 00000000000..322521ee881 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrapTheTrespassers.java @@ -0,0 +1,118 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.VoteHandler; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class TrapTheTrespassers extends CardImpl { + + public TrapTheTrespassers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + // Secret council -- Each player secretly votes for a creature you don't control, then those votes are revealed. For each creature with one or more votes, put that many stun counters on it, then tap it. + this.getSpellAbility().addEffect(new TrapTheTrespassersEffect()); + this.getSpellAbility().setAbilityWord(AbilityWord.SECRET_COUNCIL); + } + + private TrapTheTrespassers(final TrapTheTrespassers card) { + super(card); + } + + @Override + public TrapTheTrespassers copy() { + return new TrapTheTrespassers(this); + } +} + +class TrapTheTrespassersEffect extends OneShotEffect { + + TrapTheTrespassersEffect() { + super(Outcome.Benefit); + staticText = "each player secretly votes for a creature you don't control, then those votes are revealed. " + + "For each creature with one or more votes, put that many stun counters on it, then tap it"; + } + + private TrapTheTrespassersEffect(final TrapTheTrespassersEffect effect) { + super(effect); + } + + @Override + public TrapTheTrespassersEffect copy() { + return new TrapTheTrespassersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!game.getBattlefield().contains(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, source, game, 1)) { + return false; + } + TrapTheTrespassersVote vote = new TrapTheTrespassersVote(source, game); + vote.doVotes(source, game); + for (Map.Entry entry : vote.getVotesPerCreature(game).entrySet()) { + entry.getKey().addCounters(CounterType.STUN.createInstance(entry.getValue()), source, game); + entry.getKey().tap(source, game); + } + return true; + } +} + +class TrapTheTrespassersVote extends VoteHandler { + + private final FilterPermanent filter; + + TrapTheTrespassersVote(Ability source, Game game) { + this.filter = new FilterCreaturePermanent( + "creature not controlled by " + game.getPlayer(source.getControllerId()).getName() + ); + this.filter.add(Predicates.not(new ControllerIdPredicate(source.getControllerId()))); + this.secret = true; + } + + @Override + protected Set getPossibleVotes(Ability source, Game game) { + return new HashSet<>(); + } + + @Override + protected Permanent playerChoose(String voteInfo, Player player, Player decidingPlayer, Ability source, Game game) { + TargetPermanent target = new TargetPermanent(filter); + target.setNotTarget(true); + decidingPlayer.choose(Outcome.UnboostCreature, target, source, game); + return game.getPermanent(target.getFirstTarget()); + } + + @Override + protected String voteName(Permanent vote) { + return vote.getIdName(); + } + + Map getVotesPerCreature(Game game) { + return playerMap + .values() + .stream() + .flatMap(Collection::stream) + .collect(Collectors.toMap(Function.identity(), x -> 1, Integer::sum)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java index 950e297ddec..96b03559b21 100644 --- a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java +++ b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java @@ -241,6 +241,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Trading Post", 288, Rarity.RARE, mage.cards.t.TradingPost.class)); cards.add(new SetCardInfo("Tranquil Cove", 340, Rarity.COMMON, mage.cards.t.TranquilCove.class)); cards.add(new SetCardInfo("Tranquil Thicket", 341, Rarity.UNCOMMON, mage.cards.t.TranquilThicket.class)); + cards.add(new SetCardInfo("Trap the Trespassers", 25, Rarity.RARE, mage.cards.t.TrapTheTrespassers.class)); cards.add(new SetCardInfo("Travel Through Caradhras", 44, Rarity.RARE, mage.cards.t.TravelThroughCaradhras.class)); cards.add(new SetCardInfo("Treasure Nabber", 230, Rarity.RARE, mage.cards.t.TreasureNabber.class)); cards.add(new SetCardInfo("Unbreakable Formation", 179, Rarity.RARE, mage.cards.u.UnbreakableFormation.class)); diff --git a/Mage/src/main/java/mage/choices/VoteHandler.java b/Mage/src/main/java/mage/choices/VoteHandler.java index e086fd08680..090684ac09e 100644 --- a/Mage/src/main/java/mage/choices/VoteHandler.java +++ b/Mage/src/main/java/mage/choices/VoteHandler.java @@ -18,7 +18,7 @@ public abstract class VoteHandler { protected final Map> playerMap = new HashMap<>(); protected VoteHandlerAI aiVoteHint = null; - private boolean secret = false; + protected boolean secret = false; public void doVotes(Ability source, Game game) { doVotes(source, game, null); @@ -189,8 +189,4 @@ public abstract class VoteHandler { .map(Map.Entry::getKey) .collect(Collectors.toSet()); } - - public void setSecret(boolean secret) { - this.secret = secret; - } }