From d996ff0e4284c66affef3c5354419a5571aab6ab Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 10 Nov 2020 20:48:10 -0500 Subject: [PATCH] [CMR] Implemented Breeches, Brazen Plunderer --- .../mage/cards/b/BreechesBrazenPlunderer.java | 227 ++++++++++++++++++ .../cards/m/MalcolmKeenEyedNavigator.java | 2 +- Mage.Sets/src/mage/sets/CommanderLegends.java | 1 + 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/b/BreechesBrazenPlunderer.java diff --git a/Mage.Sets/src/mage/cards/b/BreechesBrazenPlunderer.java b/Mage.Sets/src/mage/cards/b/BreechesBrazenPlunderer.java new file mode 100644 index 0000000000..7da4f15eb5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BreechesBrazenPlunderer.java @@ -0,0 +1,227 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.PartnerAbility; +import mage.cards.*; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.DamagedPlayerBatchEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.ManaPoolItem; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BreechesBrazenPlunderer extends CardImpl { + + public BreechesBrazenPlunderer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + + // Whenever one or more Pirates you control deal damage to your opponents, exile the top card of each of those opponents' libraries. You may play those cards this turn, and you may spend mana as though it were mana of any color to cast those spells. + this.addAbility(new BreechesBrazenPlundererTriggeredAbility()); + + // Partner + this.addAbility(PartnerAbility.getInstance()); + } + + private BreechesBrazenPlunderer(final BreechesBrazenPlunderer card) { + super(card); + } + + @Override + public BreechesBrazenPlunderer copy() { + return new BreechesBrazenPlunderer(this); + } +} + +class BreechesBrazenPlundererTriggeredAbility extends TriggeredAbilityImpl { + + BreechesBrazenPlundererTriggeredAbility() { + super(Zone.BATTLEFIELD, null); + } + + private BreechesBrazenPlundererTriggeredAbility(final BreechesBrazenPlundererTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER_BATCH; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + DamagedPlayerBatchEvent dEvent = (DamagedPlayerBatchEvent) event; + Set<UUID> opponents = new HashSet<>(); + for (DamagedEvent damagedEvent : dEvent.getEvents()) { + Permanent permanent = game.getPermanent(damagedEvent.getSourceId()); + if (permanent == null + || !permanent.isControlledBy(getControllerId()) + || !permanent.hasSubtype(SubType.PIRATE, game) + || !game.getOpponents(getControllerId()).contains(damagedEvent.getTargetId())) { + continue; + } + opponents.add(damagedEvent.getTargetId()); + } + if (opponents.size() < 1) { + return false; + } + this.getEffects().clear(); + this.addEffect(new BreechesBrazenPlundererEffect(opponents)); + return true; + } + + @Override + public BreechesBrazenPlundererTriggeredAbility copy() { + return new BreechesBrazenPlundererTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever one or more Pirates you control deal damage to your opponents, " + + "exile the top card of each of those opponents' libraries. You may play those cards this turn, " + + "and you may spend mana as though it were mana of any color to cast those spells."; + } +} + +class BreechesBrazenPlundererEffect extends OneShotEffect { + + private final Set<UUID> opponentIds = new HashSet<>(); + + BreechesBrazenPlundererEffect(Set<UUID> opponentIds) { + super(Outcome.Benefit); + this.opponentIds.addAll(opponentIds); + } + + private BreechesBrazenPlundererEffect(final BreechesBrazenPlundererEffect effect) { + super(effect); + this.opponentIds.addAll(effect.opponentIds); + } + + @Override + public BreechesBrazenPlundererEffect copy() { + return new BreechesBrazenPlundererEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(); + opponentIds + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getLibrary) + .map(library -> library.getFromTop(game)) + .forEach(cards::add); + player.moveCards(cards, Zone.EXILED, source, game); + cards.removeIf(uuid -> game.getState().getZone(uuid) != Zone.EXILED); + if (cards.isEmpty()) { + return false; + } + for (Card card : cards.getCards(game)) { + game.addEffect(new BreechesBrazenPlundererCastEffect(new MageObjectReference(card, game)), source); + game.addEffect(new BreechesBrazenPlundererManaEffect().setTargetPointer(new FixedTarget(card, game)), source); + } + return true; + } +} + +class BreechesBrazenPlundererCastEffect extends AsThoughEffectImpl { + + private final MageObjectReference mor; + + BreechesBrazenPlundererCastEffect(MageObjectReference mor) { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + this.mor = mor; + } + + private BreechesBrazenPlundererCastEffect(final BreechesBrazenPlundererCastEffect effect) { + super(effect); + this.mor = effect.mor; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public BreechesBrazenPlundererCastEffect copy() { + return new BreechesBrazenPlundererCastEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + if (mor.getCard(game) == null) { + discard(); + return false; + } + return mor.refersTo(sourceId, game) && source.isControlledBy(affectedControllerId); + } +} + +class BreechesBrazenPlundererManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + BreechesBrazenPlundererManaEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.EndOfTurn, Outcome.Benefit); + } + + private BreechesBrazenPlundererManaEffect(final BreechesBrazenPlundererManaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public BreechesBrazenPlundererManaEffect copy() { + return new BreechesBrazenPlundererManaEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + objectId = CardUtil.getMainCardId(game, objectId); // for split cards + FixedTarget fixedTarget = ((FixedTarget) getTargetPointer()); + return source.isControlledBy(affectedControllerId) + && Objects.equals(objectId, fixedTarget.getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MalcolmKeenEyedNavigator.java b/Mage.Sets/src/mage/cards/m/MalcolmKeenEyedNavigator.java index 6278dcc58d..4a64d610c8 100644 --- a/Mage.Sets/src/mage/cards/m/MalcolmKeenEyedNavigator.java +++ b/Mage.Sets/src/mage/cards/m/MalcolmKeenEyedNavigator.java @@ -103,4 +103,4 @@ class MalcolmKeenEyedNavigatorTriggeredAbility extends TriggeredAbilityImpl { return "Whenever one or more Pirates you control deal damage to your opponents, " + "you create a Treasure token for each opponent dealt damage."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/CommanderLegends.java b/Mage.Sets/src/mage/sets/CommanderLegends.java index b615a126ec..8503f17eb0 100644 --- a/Mage.Sets/src/mage/sets/CommanderLegends.java +++ b/Mage.Sets/src/mage/sets/CommanderLegends.java @@ -91,6 +91,7 @@ public final class CommanderLegends extends ExpansionSet { cards.add(new SetCardInfo("Brass Herald", 301, Rarity.UNCOMMON, mage.cards.b.BrassHerald.class)); cards.add(new SetCardInfo("Brass Squire", 460, Rarity.UNCOMMON, mage.cards.b.BrassSquire.class)); cards.add(new SetCardInfo("Brazen Freebooter", 164, Rarity.COMMON, mage.cards.b.BrazenFreebooter.class)); + cards.add(new SetCardInfo("Breeches, Brazen Plunderer", 165, Rarity.UNCOMMON, mage.cards.b.BreechesBrazenPlunderer.class)); cards.add(new SetCardInfo("Briarblade Adept", 111, Rarity.COMMON, mage.cards.b.BriarbladeAdept.class)); cards.add(new SetCardInfo("Brinelin, the Moon Kraken", 60, Rarity.UNCOMMON, mage.cards.b.BrinelinTheMoonKraken.class)); cards.add(new SetCardInfo("Bruse Tarl, Boorish Herder", 517, Rarity.MYTHIC, mage.cards.b.BruseTarlBoorishHerder.class));