[WHO] Implement Sycorax Commander

This commit is contained in:
theelk801 2025-04-23 14:20:46 -04:00
parent b35185872d
commit dfd3e5e10d
5 changed files with 172 additions and 94 deletions

View file

@ -1,33 +1,34 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.cards.CardSetInfo;
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
import mage.cards.*;
import mage.choices.FaceVillainousChoice;
import mage.choices.VillainousChoice;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.MageObject;
import mage.util.CardUtil;
import java.util.UUID;
/**
*
* @author padfoot
*/
public final class EnsnaredByTheMara extends CardImpl {
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.PlayForFree, new EnsnaredByTheMaraFirstChoice(), new EnsnaredByTheMaraSecondChoice()
);
public EnsnaredByTheMara(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}");
// Each opponent faces a villainous choice -- They exile cards from the top of their library until they exile a nonland card, then you may cast that card without paying its mana cost, or that player exiles the top four cards of their library and Ensnared by the Mara deals damage equal to the total mana value of those exiled cards to that player.
this.getSpellAbility().addEffect(new EnsnaredByTheMaraEffect());
this.getSpellAbility().addEffect(new FaceVillainousChoiceOpponentsEffect(choice));
}
private EnsnaredByTheMara(final EnsnaredByTheMara card) {
@ -40,45 +41,15 @@ public final class EnsnaredByTheMara extends CardImpl {
}
}
class EnsnaredByTheMaraEffect extends OneShotEffect {
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.PlayForFree, new EnsnaredByTheMaraFirstChoice(), new EnsnaredByTheMaraSecondChoice()
);
EnsnaredByTheMaraEffect() {
super(Outcome.Benefit);
staticText = "each opponent " + choice.generateRule();
}
private EnsnaredByTheMaraEffect(final EnsnaredByTheMaraEffect effect) {
super(effect);
}
@Override
public EnsnaredByTheMaraEffect copy() {
return new EnsnaredByTheMaraEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
choice.faceChoice(player, game, source);
}
return true;
}
}
class EnsnaredByTheMaraFirstChoice extends VillainousChoice {
EnsnaredByTheMaraFirstChoice() {
super("They exile cards from the top of their library until they exile a nonland card, then you may cast that card without paying its mana cost","Exile a card for {controller} to cast for free");
super("They exile cards from the top of their library until they exile a nonland card, then you may cast that card without paying its mana cost", "Exile a card for {controller} to cast for free");
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
for (Card card : player.getLibrary().getCards(game)) {
for (Card card : player.getLibrary().getCards(game)) {
player.moveCards(card, Zone.EXILED, source, game);
if (!card.isLand(game)) {
CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
@ -91,20 +62,19 @@ class EnsnaredByTheMaraFirstChoice extends VillainousChoice {
class EnsnaredByTheMaraSecondChoice extends VillainousChoice {
EnsnaredByTheMaraSecondChoice() {
super("that player exiles the top four cards of their library and {this} deals damage equal to the total mana value of those exiled cards to that player","exile four cards and take damage");
super("that player exiles the top four cards of their library and {this} deals damage equal to the total mana value of those exiled cards to that player", "exile four cards and take damage");
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
int totalManaValue = 0;
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
player.moveCards(cards, Zone.EXILED, source, game);
totalManaValue = cards
.getCards(game)
.stream()
.mapToInt(MageObject::getManaValue)
.sum();
player.damage(totalManaValue, source, game);
return true;
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
player.moveCards(cards, Zone.EXILED, source, game);
int totalManaValue = cards
.getCards(game)
.stream()
.mapToInt(MageObject::getManaValue)
.sum();
player.damage(totalManaValue, source, game);
return true;
}
}

View file

@ -0,0 +1,92 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.FaceVillainousChoice;
import mage.choices.VillainousChoice;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SycoraxCommander extends CardImpl {
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.Discard, new SycoraxCommanderFirstChoice(), new SycoraxCommanderSecondChoice()
);
public SycoraxCommander(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
this.subtype.add(SubType.ALIEN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// Sanctified Rules of Combat -- When Sycorax Commander enters the battlefield, each opponent faces a villainous choice -- That opponent discards all the cards in their hand, then draws that many cards minus one, or Sycorax Commander deals damage to that player equal to the number of cards in their hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new FaceVillainousChoiceOpponentsEffect(choice)
).withFlavorWord("Sanctified Rules of Combat"));
}
private SycoraxCommander(final SycoraxCommander card) {
super(card);
}
@Override
public SycoraxCommander copy() {
return new SycoraxCommander(this);
}
}
class SycoraxCommanderFirstChoice extends VillainousChoice {
SycoraxCommanderFirstChoice() {
super(
"That opponent discards all the cards in their hand, then draws that many cards minus one",
"Discard your hand and draw one less card"
);
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
int discarded = player.discard(player.getHand(), false, source, game).size();
if (discarded > 0) {
player.drawCards(discarded - 1, source, game);
}
return true;
}
}
class SycoraxCommanderSecondChoice extends VillainousChoice {
SycoraxCommanderSecondChoice() {
super(
"{this} deals damage to that player equal to the number of cards in their hand",
"Take damage equal to the number of cards in your hand"
);
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
return player.damage(player.getHand().size(), source, game) > 0;
}
}

View file

@ -2,15 +2,15 @@ package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AffinityEffect;
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.FaceVillainousChoice;
@ -33,6 +33,9 @@ public final class TheDalekEmperor extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.DALEK, "Daleks");
private static final Hint hint = new ValueHint("Daleks you control", new PermanentsOnBattlefieldCount(filter));
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.Sacrifice, new TheDalekEmperorFirstChoice(), new TheDalekEmperorSecondChoice()
);
public TheDalekEmperor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}{B}{R}");
@ -51,9 +54,7 @@ public final class TheDalekEmperor extends CardImpl {
)));
// At the beginning of combat on your turn, each opponent faces a villainous choice -- That player sacrifices a creature they control, or you create a 3/3 black Dalek artifact creature token with menace.
this.addAbility(new BeginningOfCombatTriggeredAbility(
new TheDalekEmperorEffect()
));
this.addAbility(new BeginningOfCombatTriggeredAbility(new FaceVillainousChoiceOpponentsEffect(choice)));
}
private TheDalekEmperor(final TheDalekEmperor card) {
@ -66,36 +67,6 @@ public final class TheDalekEmperor extends CardImpl {
}
}
class TheDalekEmperorEffect extends OneShotEffect {
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.Sacrifice, new TheDalekEmperorFirstChoice(), new TheDalekEmperorSecondChoice()
);
TheDalekEmperorEffect() {
super(Outcome.Benefit);
staticText = "each opponent " + choice.generateRule();
}
private TheDalekEmperorEffect(final TheDalekEmperorEffect effect) {
super(effect);
}
@Override
public TheDalekEmperorEffect copy() {
return new TheDalekEmperorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
choice.faceChoice(player, game, source);
}
return true;
}
}
class TheDalekEmperorFirstChoice extends VillainousChoice {
TheDalekEmperorFirstChoice() {

View file

@ -803,10 +803,10 @@ public final class DoctorWho extends ExpansionSet {
cards.add(new SetCardInfo("Swamp", 201, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swords to Plowshares", 212, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swords to Plowshares", 803, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Sycorax Commander", 1036, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Sycorax Commander", 161, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Sycorax Commander", 445, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Sycorax Commander", 766, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sycorax Commander", 1036, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sycorax Commander", 161, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sycorax Commander", 445, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sycorax Commander", 766, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Talisman of Conviction", 247, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Talisman of Conviction", 838, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Talisman of Creativity", 248, Rarity.UNCOMMON, mage.cards.t.TalismanOfCreativity.class, NON_FULL_USE_VARIOUS));

View file

@ -0,0 +1,45 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.choices.FaceVillainousChoice;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public class FaceVillainousChoiceOpponentsEffect extends OneShotEffect {
private final FaceVillainousChoice choice;
public FaceVillainousChoiceOpponentsEffect(FaceVillainousChoice choice) {
super(Outcome.Benefit);
this.choice = choice;
staticText = "each opponent " + choice.generateRule();
}
private FaceVillainousChoiceOpponentsEffect(final FaceVillainousChoiceOpponentsEffect effect) {
super(effect);
this.choice = effect.choice;
}
@Override
public FaceVillainousChoiceOpponentsEffect copy() {
return new FaceVillainousChoiceOpponentsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
if (player != null) {
choice.faceChoice(player, game, source);
}
}
return true;
}
}