From 69517f998f334d0431ff0d7fb9355f2c6b3e9e71 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sun, 22 Oct 2023 14:34:27 +0200 Subject: [PATCH] [LCI] Implement Breeches, Eager Pillager (#11333) --- .../mage/cards/b/BreechesEagerPillager.java | 76 +++++++++++++++++++ .../src/mage/sets/LostCavernsOfIxalan.java | 1 + Mage/src/main/java/mage/abilities/Modes.java | 14 ++-- 3 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BreechesEagerPillager.java diff --git a/Mage.Sets/src/mage/cards/b/BreechesEagerPillager.java b/Mage.Sets/src/mage/cards/b/BreechesEagerPillager.java new file mode 100644 index 00000000000..eacf23cd4da --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BreechesEagerPillager.java @@ -0,0 +1,76 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEndOfTurnEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.abilities.hint.common.ModesAlreadyUsedHint; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.common.FilterControlledPermanent; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class BreechesEagerPillager extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.PIRATE, "Pirate you control"); + + public BreechesEagerPillager(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // Whenever a Pirate you control attacks, choose one that hasn't been chosen this turn -- + // * Create a Treasure token. + Ability ability = new AttacksCreatureYouControlTriggeredAbility( + new CreateTokenEffect(new TreasureToken()), false, filter + ); + ability.setModeTag("treasure"); + ability.getModes().setEachModeOnlyOnce(true); + ability.getModes().setResetEachTurn(true); + + // * Target creature can't block this turn. + Mode mode = new Mode(new CantBlockTargetEffect(Duration.EndOfTurn)) + .setModeTag("target can't block"); + mode.addTarget(new TargetCreaturePermanent()); + ability.addMode(mode); + + // * Exile the top card of your library. You may play it this turn. + ability.addMode(new Mode( + new ExileTopXMayPlayUntilEndOfTurnEffect(1) + .setText("exile the top card of your library. You may play it this turn") + ).setModeTag("exile top card")); + + ability.addHint(ModesAlreadyUsedHint.instance); + this.addAbility(ability); + } + + private BreechesEagerPillager(final BreechesEagerPillager card) { + super(card); + } + + @Override + public BreechesEagerPillager copy() { + return new BreechesEagerPillager(this); + } +} diff --git a/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java index 0b2e149f126..14ffa1000af 100644 --- a/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java @@ -21,6 +21,7 @@ public final class LostCavernsOfIxalan extends ExpansionSet { this.hasBoosters = false; // TODO: enable boosters this.hasBasicLands = true; + cards.add(new SetCardInfo("Breeches, Eager Pillager", 137, Rarity.RARE, mage.cards.b.BreechesEagerPillager.class)); cards.add(new SetCardInfo("Cavern of Souls", 269, Rarity.MYTHIC, mage.cards.c.CavernOfSouls.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ghalta, Stampede Tyrant", 185, Rarity.MYTHIC, mage.cards.g.GhaltaStampedeTyrant.class)); diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java index 97accb99140..dd85fb9024b 100644 --- a/Mage/src/main/java/mage/abilities/Modes.java +++ b/Mage/src/main/java/mage/abilities/Modes.java @@ -102,7 +102,7 @@ public class Modes extends LinkedHashMap { } public Stream streamAlreadySelected(Ability source, Game game) { - Set selected = getAlreadySelectedModes(source, game); + Set selected = getAlreadySelectedModes(source, game, true); return stream().filter(m -> selected.contains(m.getId())); } @@ -298,7 +298,7 @@ public class Modes extends LinkedHashMap { if (this.size() == this.getMinModes() && !isEachModeMoreThanOnce()) { Set onceSelectedModes = null; if (isEachModeOnlyOnce()) { - onceSelectedModes = getAlreadySelectedModes(source, game); + onceSelectedModes = getAlreadySelectedModes(source, game, true); } for (Mode mode : this.values()) { if ((!isEachModeOnlyOnce() || onceSelectedModes == null || !onceSelectedModes.contains(mode.getId())) @@ -383,7 +383,7 @@ public class Modes extends LinkedHashMap { } private void clearAlreadySelectedModes(Ability source, Game game) { - for (UUID modeId : getAlreadySelectedModes(source, game)) { + for (UUID modeId : getAlreadySelectedModes(source, game, false)) { String key = getKey(source, game, modeId); game.getState().setValue(key, false); } @@ -421,8 +421,12 @@ public class Modes extends LinkedHashMap { // The already once selected modes for a modal card are stored as a state value // That's important for modal abilities with modes that can only selected once while the object stays in its zone @SuppressWarnings("unchecked") - private Set getAlreadySelectedModes(Ability source, Game game) { + private Set getAlreadySelectedModes(Ability source, Game game, boolean ignoreOldData) { Set onceSelectedModes = new HashSet<>(); + if (ignoreOldData && this.isResetEachTurn() && getTurnNum(game, source) != game.getTurnNum()) { + // Selected modes is not for current turn, so we ignore any value that may be there. + return onceSelectedModes; + } for (UUID modeId : this.keySet()) { Object exist = game.getState().getValue(getKey(source, game, modeId)); if (exist == Boolean.TRUE) { @@ -464,7 +468,7 @@ public class Modes extends LinkedHashMap { if (isEachModeMoreThanOnce()) { nonAvailableModes = new HashSet<>(); } else { - nonAvailableModes = getAlreadySelectedModes(source, game); + nonAvailableModes = getAlreadySelectedModes(source, game, true); } for (Mode mode : this.values()) { if (isEachModeOnlyOnce() && nonAvailableModes.contains(mode.getId())) {