mirror of
https://github.com/correl/mage.git
synced 2024-11-14 19:19:32 +00:00
[SNC] Implemented Riveteers Charm
This commit is contained in:
parent
28e62abcce
commit
be6dd5263d
6 changed files with 174 additions and 33 deletions
|
@ -16,7 +16,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.common.TargetAttackingCreature;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -45,7 +45,7 @@ public final class RaffineSchemingSeer extends CardImpl {
|
|||
|
||||
// Whenever you attack, target creature connives X, where X is the number of attacking creatures.
|
||||
Ability ability = new AttacksWithCreaturesTriggeredAbility(new ConniveTargetEffect(xValue), 1);
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
ability.addTarget(new TargetAttackingCreature());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
130
Mage.Sets/src/mage/cards/r/RiveteersCharm.java
Normal file
130
Mage.Sets/src/mage/cards/r/RiveteersCharm.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ExileGraveyardAllTargetPlayerEffect;
|
||||
import mage.abilities.effects.common.SacrificeEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
|
||||
import mage.filter.predicate.permanent.MaxManaValueControlledPermanentPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class RiveteersCharm extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent(
|
||||
"creature or planeswalker they control with the highest mana value " +
|
||||
"among creatures and planeswalkers they control"
|
||||
);
|
||||
|
||||
static {
|
||||
filter.add(MaxManaValueControlledPermanentPredicate.instance);
|
||||
}
|
||||
|
||||
public RiveteersCharm(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{R}{G}");
|
||||
|
||||
// Choose one —
|
||||
// • Target opponent sacrifices a creature or planeswalker they control with the highest mana value among creatures and planeswalkers they control.
|
||||
this.getSpellAbility().addEffect(new SacrificeEffect(filter, 1, "target opponent"));
|
||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||
|
||||
// • Exile the top three cards of your library. Until your next end step, you may play those cards.
|
||||
this.getSpellAbility().addMode(new Mode(new RiveteersCharmEffect()));
|
||||
this.getSpellAbility().addWatcher(new RiveteersCharmWatcher());
|
||||
|
||||
// • Exile target player's graveyard.
|
||||
this.getSpellAbility().addMode(new Mode(new ExileGraveyardAllTargetPlayerEffect()).addTarget(new TargetPlayer()));
|
||||
}
|
||||
|
||||
private RiveteersCharm(final RiveteersCharm card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RiveteersCharm copy() {
|
||||
return new RiveteersCharm(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RiveteersCharmEffect extends OneShotEffect {
|
||||
|
||||
RiveteersCharmEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile the top three cards of your library. Until your next end step, you may play those cards";
|
||||
}
|
||||
|
||||
private RiveteersCharmEffect(final RiveteersCharmEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RiveteersCharmEffect copy() {
|
||||
return new RiveteersCharmEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3));
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(cards, Zone.EXILED, source, game);
|
||||
int count = RiveteersCharmWatcher.getCount(game, source);
|
||||
Condition condition = (g, s) -> RiveteersCharmWatcher.getCount(g, s) == count;
|
||||
for (Card card : cards.getCards(game)) {
|
||||
CardUtil.makeCardPlayable(game, source, card, Duration.Custom, false, null, condition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class RiveteersCharmWatcher extends Watcher {
|
||||
|
||||
private final Map<UUID, Integer> playerMap = new HashMap<>();
|
||||
|
||||
RiveteersCharmWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
switch (event.getType()) {
|
||||
case END_TURN_STEP_PRE:
|
||||
playerMap.compute(game.getActivePlayerId(), CardUtil::setOrIncrementValue);
|
||||
return;
|
||||
case BEGINNING_PHASE_PRE:
|
||||
if (game.getTurnNum() == 1) {
|
||||
playerMap.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int getCount(Game game, Ability source) {
|
||||
return game
|
||||
.getState()
|
||||
.getWatcher(RiveteersCharmWatcher.class)
|
||||
.playerMap
|
||||
.getOrDefault(source.getControllerId(), 0);
|
||||
}
|
||||
}
|
|
@ -1,19 +1,13 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.effects.common.SacrificeOpponentsEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.predicate.permanent.MaxManaValueControlledPermanentPredicate;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +21,7 @@ public final class SoulShatter extends CardImpl {
|
|||
);
|
||||
|
||||
static {
|
||||
filter.add(SoulShatterPredicate.instance);
|
||||
filter.add(MaxManaValueControlledPermanentPredicate.instance);
|
||||
}
|
||||
|
||||
public SoulShatter(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
@ -46,25 +40,3 @@ public final class SoulShatter extends CardImpl {
|
|||
return new SoulShatter(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum SoulShatterPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent();
|
||||
|
||||
static {
|
||||
filter.add(TargetController.YOU.getControllerPredicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
int cmc = game.getBattlefield()
|
||||
.getActivePermanents(filter, input.getPlayerId(), game)
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.max()
|
||||
.orElse(0);
|
||||
return input.getObject().getManaValue() >= cmc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public final class StreetsOfNewCapenna extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Plains", 272, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Raffine's Tower", 254, Rarity.RARE, mage.cards.r.RaffinesTower.class));
|
||||
cards.add(new SetCardInfo("Raffine, Scheming Seer", 213, Rarity.MYTHIC, mage.cards.r.RaffineSchemingSeer.class));
|
||||
cards.add(new SetCardInfo("Riveteers Charm", 217, Rarity.UNCOMMON, mage.cards.r.RiveteersCharm.class));
|
||||
cards.add(new SetCardInfo("Spara's Headquarters", 257, Rarity.RARE, mage.cards.s.SparasHeadquarters.class));
|
||||
cards.add(new SetCardInfo("Swamp", 276, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Xander's Lounge", 260, Rarity.RARE, mage.cards.x.XandersLounge.class));
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package mage.filter.predicate.permanent;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public enum MaxManaValueControlledPermanentPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent();
|
||||
|
||||
static {
|
||||
filter.add(TargetController.YOU.getControllerPredicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
int cmc = game.getBattlefield()
|
||||
.getActivePermanents(filter, input.getPlayerId(), input.getSource(), game)
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.max()
|
||||
.orElse(0);
|
||||
return input.getObject().getManaValue() >= cmc;
|
||||
}
|
||||
}
|
|
@ -43923,7 +43923,8 @@ Jetmir, Nexus of Revels|Streets of New Capenna|193|M|{1}{R}{G}{W}|Legendary Crea
|
|||
Lord Xander, the Collector|Streets of New Capenna|197|M|{4}{U}{B}{R}|Legendary Creature - Vampire Demon Noble|6|6|When Lord Xander, the Collector enters the battlefield, target opponent discards half the cards in their hand, rounded down.$Whenever Lord Xander attacks, defending player mills half their library, rounded down.$When Lord Xander dies, target opponent sacrifices half the nonland permanents they control, rounded down.|
|
||||
Maestros Charm|Streets of New Capenna|199|U|{U}{B}{R}|Instant|||Choose one —$• Look at the top five cards of your library. Put one of those cards into your hand and the rest into your graveyard.$• Each opponent loses 3 life and you gain 3 life.$• Maestros Charm deals 5 damage to target creature or planeswalker.|
|
||||
Obscura Charm|Streets of New Capenna|208|U|{W}{U}{B}|Instant|||Choose one —$• Return target multicolored permanent card with mana value 3 or less from your graveyard to the battlefield tapped.$• Counter target instant or sorcery spell.$• Destroy target creature or planeswalker with mana value 3 or less.|
|
||||
Raffine, Scheming Seer|Streets of New Capenna|213|M|{W}{U}{B}|Legendary Creature - Sphinx Demon|1|4|Flying, ward {1}$Whenever you attack, target creature connives X, where X is the number of attacking creatures.|
|
||||
Raffine, Scheming Seer|Streets of New Capenna|213|M|{W}{U}{B}|Legendary Creature - Sphinx Demon|1|4|Flying, ward {1}$Whenever you attack, target attacking creature connives X, where X is the number of attacking creatures.|
|
||||
Riveteers Charm|Streets of New Capenna|217|U|{B}{R}{G}|Instant|||Choose one —$• Target opponent sacrifices a creature or planeswalker they control with the highest mana value among creatures and planeswalkers they control.$• Exile the top three cards of your library. Until your next end step, you may play those cards.$• Exile target player's graveyard.|
|
||||
Jetmir's Garden|Streets of New Capenna|250|R||Land - Mountain Forest Plains|||({T}: Add {R}, {G}, or {W}.)$Jetmir's Garden enters the battlefield tapped.$Cycling {3}|
|
||||
Raffine's Tower|Streets of New Capenna|254|R||Land - Plains Island Swamp|||({T}: Add {W}, {U}, or {B}.)$Raffine's Tower enters the battlefield tapped.$Cycling {3}|
|
||||
Spara's Headquarters|Streets of New Capenna|257|R||Land - Forest Plains Island|||({T}: Add {G}, {W}, or {U}.)$Spara's Headquarters enters the battlefield tapped.$Cycling {3}|
|
||||
|
|
Loading…
Reference in a new issue