mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
[TDM] Implement Severance Priest
This commit is contained in:
parent
61c771a905
commit
5ae4d7c0bc
4 changed files with 181 additions and 61 deletions
98
Mage.Sets/src/mage/cards/s/SeverancePriest.java
Normal file
98
Mage.Sets/src/mage/cards/s/SeverancePriest.java
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CreateXXTokenExiledEffectManaValueEffect;
|
||||||
|
import mage.abilities.keyword.DeathtouchAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.token.SpiritXXToken;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetCard;
|
||||||
|
import mage.target.common.TargetCardInHand;
|
||||||
|
import mage.target.common.TargetOpponent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class SeverancePriest extends CardImpl {
|
||||||
|
|
||||||
|
public SeverancePriest(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DJINN);
|
||||||
|
this.subtype.add(SubType.CLERIC);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Deathtouch
|
||||||
|
this.addAbility(DeathtouchAbility.getInstance());
|
||||||
|
|
||||||
|
// When this creature enters, target opponent reveals their hand. You may choose a nonland card from it. If you do, exile that card.
|
||||||
|
Ability ability = new EntersBattlefieldTriggeredAbility(new SeverancePriestEffect());
|
||||||
|
ability.addTarget(new TargetOpponent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// When this creature leaves the battlefield, the exiled card's owner creates an X/X white Spirit creature token, where X is the mana value of the exiled card.
|
||||||
|
this.addAbility(new LeavesBattlefieldTriggeredAbility(
|
||||||
|
new CreateXXTokenExiledEffectManaValueEffect(SpiritXXToken::new, "white Spirit")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SeverancePriest(final SeverancePriest card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SeverancePriest copy() {
|
||||||
|
return new SeverancePriest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SeverancePriestEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
SeverancePriestEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "target opponent reveals their hand. You may choose " +
|
||||||
|
"a nonland card from it. If you do, exile that card";
|
||||||
|
}
|
||||||
|
|
||||||
|
private SeverancePriestEffect(final SeverancePriestEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SeverancePriestEffect copy() {
|
||||||
|
return new SeverancePriestEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
|
if (controller == null || opponent == null || opponent.getHand().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
opponent.revealCards(source, opponent.getHand(), game);
|
||||||
|
TargetCard target = new TargetCardInHand(0, 1, StaticFilters.FILTER_CARD_NON_LAND);
|
||||||
|
controller.choose(Outcome.Discard, opponent.getHand(), target, source, game);
|
||||||
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
|
return card != null && controller.moveCardsToExile(
|
||||||
|
card, source, game, true,
|
||||||
|
CardUtil.getExileZoneId(game, source),
|
||||||
|
CardUtil.getSourceName(game, source)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +1,24 @@
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.common.CreateXXTokenExiledEffectManaValueEffect;
|
||||||
import mage.abilities.effects.common.ExileTargetForSourceEffect;
|
import mage.abilities.effects.common.ExileTargetForSourceEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ComparisonType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterNonlandPermanent;
|
import mage.filter.common.FilterNonlandPermanent;
|
||||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||||
import mage.filter.predicate.permanent.TokenPredicate;
|
import mage.filter.predicate.permanent.TokenPredicate;
|
||||||
import mage.game.ExileZone;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.game.permanent.token.CustomIllusionToken;
|
import mage.game.permanent.token.CustomIllusionToken;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,7 +50,9 @@ public final class SkyclaveApparition extends CardImpl {
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// When Skyclave Apparition leaves the battlefield, the exiled card's owner creates an X/X blue Illusion creature token, where X is the converted mana cost of the exiled card.
|
// When Skyclave Apparition leaves the battlefield, the exiled card's owner creates an X/X blue Illusion creature token, where X is the converted mana cost of the exiled card.
|
||||||
this.addAbility(new LeavesBattlefieldTriggeredAbility(new SkyclaveApparitionEffect(), false));
|
this.addAbility(new LeavesBattlefieldTriggeredAbility(
|
||||||
|
new CreateXXTokenExiledEffectManaValueEffect(CustomIllusionToken::new, "blue Illusion")
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SkyclaveApparition(final SkyclaveApparition card) {
|
private SkyclaveApparition(final SkyclaveApparition card) {
|
||||||
|
|
@ -67,50 +64,3 @@ public final class SkyclaveApparition extends CardImpl {
|
||||||
return new SkyclaveApparition(this);
|
return new SkyclaveApparition(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SkyclaveApparitionEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
SkyclaveApparitionEffect() {
|
|
||||||
super(Outcome.Benefit);
|
|
||||||
staticText = "the exiled card's owner creates an X/X blue Illusion creature token, " +
|
|
||||||
"where X is the mana value of the exiled card";
|
|
||||||
}
|
|
||||||
|
|
||||||
private SkyclaveApparitionEffect(final SkyclaveApparitionEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkyclaveApparitionEffect copy() {
|
|
||||||
return new SkyclaveApparitionEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield");
|
|
||||||
ExileZone exile = game.getExile().getExileZone(
|
|
||||||
CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game))
|
|
||||||
);
|
|
||||||
if (exile == null || exile.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// From ZNR Release Notes:
|
|
||||||
// https://magic.wizards.com/en/articles/archive/feature/zendikar-rising-release-notes-2020-09-10
|
|
||||||
// If Skyclave Apparition's first ability exiled more than one card owned by a single player,
|
|
||||||
// that player creates a token with power and toughness equal to the sum of those cards' converted mana costs.
|
|
||||||
// If the first ability exiled cards owned by more than one player, each of those players creates a token
|
|
||||||
// with power and toughness equal to the sum of the converted mana costs of all cards exiled by the first ability.
|
|
||||||
Set<UUID> owners = new HashSet<>();
|
|
||||||
int totalCMC = exile
|
|
||||||
.getCards(game)
|
|
||||||
.stream()
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.map(card -> owners.add(card.getOwnerId()) ? card : card)
|
|
||||||
.mapToInt(MageObject::getManaValue)
|
|
||||||
.sum();
|
|
||||||
for (UUID playerId : owners) {
|
|
||||||
new CustomIllusionToken(totalCMC).putOntoBattlefield(1, game, source, playerId);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
package mage.sets;
|
package mage.sets;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import mage.cards.ExpansionSet;
|
import mage.cards.ExpansionSet;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.constants.SetType;
|
import mage.constants.SetType;
|
||||||
|
|
@ -222,6 +219,7 @@ public final class TarkirDragonstorm extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Scavenger Regent", 90, Rarity.RARE, mage.cards.s.ScavengerRegent.class));
|
cards.add(new SetCardInfo("Scavenger Regent", 90, Rarity.RARE, mage.cards.s.ScavengerRegent.class));
|
||||||
cards.add(new SetCardInfo("Scoured Barrens", 267, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
|
cards.add(new SetCardInfo("Scoured Barrens", 267, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
|
||||||
cards.add(new SetCardInfo("Seize Opportunity", 119, Rarity.COMMON, mage.cards.s.SeizeOpportunity.class));
|
cards.add(new SetCardInfo("Seize Opportunity", 119, Rarity.COMMON, mage.cards.s.SeizeOpportunity.class));
|
||||||
|
cards.add(new SetCardInfo("Severance Priest", 222, Rarity.RARE, mage.cards.s.SeverancePriest.class));
|
||||||
cards.add(new SetCardInfo("Shiko, Paragon of the Way", 223, Rarity.MYTHIC, mage.cards.s.ShikoParagonOfTheWay.class));
|
cards.add(new SetCardInfo("Shiko, Paragon of the Way", 223, Rarity.MYTHIC, mage.cards.s.ShikoParagonOfTheWay.class));
|
||||||
cards.add(new SetCardInfo("Shock Brigade", 120, Rarity.COMMON, mage.cards.s.ShockBrigade.class));
|
cards.add(new SetCardInfo("Shock Brigade", 120, Rarity.COMMON, mage.cards.s.ShockBrigade.class));
|
||||||
cards.add(new SetCardInfo("Shocking Sharpshooter", 121, Rarity.UNCOMMON, mage.cards.s.ShockingSharpshooter.class));
|
cards.add(new SetCardInfo("Shocking Sharpshooter", 121, Rarity.UNCOMMON, mage.cards.s.ShockingSharpshooter.class));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.game.ExileZone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.permanent.token.Token;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public class CreateXXTokenExiledEffectManaValueEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private final Function<Integer, Token> tokenMaker;
|
||||||
|
|
||||||
|
public CreateXXTokenExiledEffectManaValueEffect(Function<Integer, Token> tokenMaker, String description) {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.tokenMaker = tokenMaker;
|
||||||
|
staticText = "the exiled card's owner creates an X/X " + description +
|
||||||
|
"creature token, where X is the mana value of the exiled card";
|
||||||
|
}
|
||||||
|
|
||||||
|
private CreateXXTokenExiledEffectManaValueEffect(final CreateXXTokenExiledEffectManaValueEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.tokenMaker = effect.tokenMaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CreateXXTokenExiledEffectManaValueEffect copy() {
|
||||||
|
return new CreateXXTokenExiledEffectManaValueEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield");
|
||||||
|
ExileZone exile = game.getExile().getExileZone(
|
||||||
|
CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game))
|
||||||
|
);
|
||||||
|
if (exile == null || exile.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// From ZNR Release Notes:
|
||||||
|
// https://magic.wizards.com/en/articles/archive/feature/zendikar-rising-release-notes-2020-09-10
|
||||||
|
// If Skyclave Apparition's first ability exiled more than one card owned by a single player,
|
||||||
|
// that player creates a token with power and toughness equal to the sum of those cards' converted mana costs.
|
||||||
|
// If the first ability exiled cards owned by more than one player, each of those players creates a token
|
||||||
|
// with power and toughness equal to the sum of the converted mana costs of all cards exiled by the first ability.
|
||||||
|
Set<UUID> owners = new HashSet<>();
|
||||||
|
int totalCMC = exile
|
||||||
|
.getCards(game)
|
||||||
|
.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(card -> {
|
||||||
|
owners.add(card.getOwnerId());
|
||||||
|
return card;
|
||||||
|
})
|
||||||
|
.mapToInt(MageObject::getManaValue)
|
||||||
|
.sum();
|
||||||
|
for (UUID playerId : owners) {
|
||||||
|
tokenMaker.apply(totalCMC).putOntoBattlefield(1, game, source, playerId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue