Skip to content

Commit dfd3e5e

Browse files
committed
[WHO] Implement Sycorax Commander
1 parent b351858 commit dfd3e5e

File tree

5 files changed

+172
-94
lines changed

5 files changed

+172
-94
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
package mage.cards.e;
22

3-
import java.util.UUID;
3+
import mage.MageObject;
44
import mage.abilities.Ability;
5-
import mage.abilities.effects.OneShotEffect;
6-
import mage.cards.Card;
7-
import mage.cards.Cards;
8-
import mage.cards.CardImpl;
9-
import mage.cards.CardsImpl;
10-
import mage.cards.CardSetInfo;
5+
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
6+
import mage.cards.*;
117
import mage.choices.FaceVillainousChoice;
128
import mage.choices.VillainousChoice;
13-
import mage.constants.*;
9+
import mage.constants.CardType;
10+
import mage.constants.Outcome;
11+
import mage.constants.Zone;
1412
import mage.game.Game;
1513
import mage.players.Player;
16-
import mage.MageObject;
1714
import mage.util.CardUtil;
1815

16+
import java.util.UUID;
17+
1918
/**
20-
*
2119
* @author padfoot
2220
*/
2321
public final class EnsnaredByTheMara extends CardImpl {
2422

23+
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
24+
Outcome.PlayForFree, new EnsnaredByTheMaraFirstChoice(), new EnsnaredByTheMaraSecondChoice()
25+
);
26+
2527
public EnsnaredByTheMara(UUID ownerId, CardSetInfo setInfo) {
2628
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}");
27-
2829

2930
// 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.
30-
this.getSpellAbility().addEffect(new EnsnaredByTheMaraEffect());
31+
this.getSpellAbility().addEffect(new FaceVillainousChoiceOpponentsEffect(choice));
3132
}
3233

3334
private EnsnaredByTheMara(final EnsnaredByTheMara card) {
@@ -40,45 +41,15 @@ public EnsnaredByTheMara copy() {
4041
}
4142
}
4243

43-
class EnsnaredByTheMaraEffect extends OneShotEffect {
44-
45-
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
46-
Outcome.PlayForFree, new EnsnaredByTheMaraFirstChoice(), new EnsnaredByTheMaraSecondChoice()
47-
);
48-
49-
EnsnaredByTheMaraEffect() {
50-
super(Outcome.Benefit);
51-
staticText = "each opponent " + choice.generateRule();
52-
}
53-
54-
private EnsnaredByTheMaraEffect(final EnsnaredByTheMaraEffect effect) {
55-
super(effect);
56-
}
57-
58-
@Override
59-
public EnsnaredByTheMaraEffect copy() {
60-
return new EnsnaredByTheMaraEffect(this);
61-
}
62-
63-
@Override
64-
public boolean apply(Game game, Ability source) {
65-
for (UUID playerId : game.getOpponents(source.getControllerId())) {
66-
Player player = game.getPlayer(playerId);
67-
choice.faceChoice(player, game, source);
68-
}
69-
return true;
70-
}
71-
}
72-
7344
class EnsnaredByTheMaraFirstChoice extends VillainousChoice {
7445
EnsnaredByTheMaraFirstChoice() {
75-
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");
46+
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");
7647
}
7748

7849
@Override
7950
public boolean doChoice(Player player, Game game, Ability source) {
8051
Player controller = game.getPlayer(source.getControllerId());
81-
for (Card card : player.getLibrary().getCards(game)) {
52+
for (Card card : player.getLibrary().getCards(game)) {
8253
player.moveCards(card, Zone.EXILED, source, game);
8354
if (!card.isLand(game)) {
8455
CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
@@ -91,20 +62,19 @@ public boolean doChoice(Player player, Game game, Ability source) {
9162

9263
class EnsnaredByTheMaraSecondChoice extends VillainousChoice {
9364
EnsnaredByTheMaraSecondChoice() {
94-
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");
65+
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");
9566
}
9667

9768
@Override
9869
public boolean doChoice(Player player, Game game, Ability source) {
99-
int totalManaValue = 0;
100-
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
101-
player.moveCards(cards, Zone.EXILED, source, game);
102-
totalManaValue = cards
103-
.getCards(game)
104-
.stream()
105-
.mapToInt(MageObject::getManaValue)
106-
.sum();
107-
player.damage(totalManaValue, source, game);
108-
return true;
70+
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
71+
player.moveCards(cards, Zone.EXILED, source, game);
72+
int totalManaValue = cards
73+
.getCards(game)
74+
.stream()
75+
.mapToInt(MageObject::getManaValue)
76+
.sum();
77+
player.damage(totalManaValue, source, game);
78+
return true;
10979
}
11080
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package mage.cards.s;
2+
3+
import mage.MageInt;
4+
import mage.abilities.Ability;
5+
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
6+
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
7+
import mage.abilities.keyword.FirstStrikeAbility;
8+
import mage.abilities.keyword.HasteAbility;
9+
import mage.cards.CardImpl;
10+
import mage.cards.CardSetInfo;
11+
import mage.choices.FaceVillainousChoice;
12+
import mage.choices.VillainousChoice;
13+
import mage.constants.CardType;
14+
import mage.constants.Outcome;
15+
import mage.constants.SubType;
16+
import mage.game.Game;
17+
import mage.players.Player;
18+
19+
import java.util.UUID;
20+
21+
/**
22+
* @author TheElk801
23+
*/
24+
public final class SycoraxCommander extends CardImpl {
25+
26+
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
27+
Outcome.Discard, new SycoraxCommanderFirstChoice(), new SycoraxCommanderSecondChoice()
28+
);
29+
30+
public SycoraxCommander(UUID ownerId, CardSetInfo setInfo) {
31+
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
32+
33+
this.subtype.add(SubType.ALIEN);
34+
this.subtype.add(SubType.SOLDIER);
35+
this.power = new MageInt(4);
36+
this.toughness = new MageInt(2);
37+
38+
// First strike
39+
this.addAbility(FirstStrikeAbility.getInstance());
40+
41+
// Haste
42+
this.addAbility(HasteAbility.getInstance());
43+
44+
// 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.
45+
this.addAbility(new EntersBattlefieldTriggeredAbility(
46+
new FaceVillainousChoiceOpponentsEffect(choice)
47+
).withFlavorWord("Sanctified Rules of Combat"));
48+
}
49+
50+
private SycoraxCommander(final SycoraxCommander card) {
51+
super(card);
52+
}
53+
54+
@Override
55+
public SycoraxCommander copy() {
56+
return new SycoraxCommander(this);
57+
}
58+
}
59+
60+
class SycoraxCommanderFirstChoice extends VillainousChoice {
61+
62+
SycoraxCommanderFirstChoice() {
63+
super(
64+
"That opponent discards all the cards in their hand, then draws that many cards minus one",
65+
"Discard your hand and draw one less card"
66+
);
67+
}
68+
69+
@Override
70+
public boolean doChoice(Player player, Game game, Ability source) {
71+
int discarded = player.discard(player.getHand(), false, source, game).size();
72+
if (discarded > 0) {
73+
player.drawCards(discarded - 1, source, game);
74+
}
75+
return true;
76+
}
77+
}
78+
79+
class SycoraxCommanderSecondChoice extends VillainousChoice {
80+
81+
SycoraxCommanderSecondChoice() {
82+
super(
83+
"{this} deals damage to that player equal to the number of cards in their hand",
84+
"Take damage equal to the number of cards in your hand"
85+
);
86+
}
87+
88+
@Override
89+
public boolean doChoice(Player player, Game game, Ability source) {
90+
return player.damage(player.getHand().size(), source, game) > 0;
91+
}
92+
}

Mage.Sets/src/mage/cards/t/TheDalekEmperor.java

+6-35
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
import mage.MageInt;
44
import mage.abilities.Ability;
5-
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
65
import mage.abilities.common.SimpleStaticAbility;
76
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
8-
import mage.abilities.effects.OneShotEffect;
97
import mage.abilities.effects.common.AffinityEffect;
8+
import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect;
109
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
1110
import mage.abilities.hint.Hint;
1211
import mage.abilities.hint.ValueHint;
1312
import mage.abilities.keyword.HasteAbility;
13+
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
1414
import mage.cards.CardImpl;
1515
import mage.cards.CardSetInfo;
1616
import mage.choices.FaceVillainousChoice;
@@ -33,6 +33,9 @@ public final class TheDalekEmperor extends CardImpl {
3333

3434
private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.DALEK, "Daleks");
3535
private static final Hint hint = new ValueHint("Daleks you control", new PermanentsOnBattlefieldCount(filter));
36+
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
37+
Outcome.Sacrifice, new TheDalekEmperorFirstChoice(), new TheDalekEmperorSecondChoice()
38+
);
3639

3740
public TheDalekEmperor(UUID ownerId, CardSetInfo setInfo) {
3841
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}{B}{R}");
@@ -51,9 +54,7 @@ public TheDalekEmperor(UUID ownerId, CardSetInfo setInfo) {
5154
)));
5255

5356
// 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.
54-
this.addAbility(new BeginningOfCombatTriggeredAbility(
55-
new TheDalekEmperorEffect()
56-
));
57+
this.addAbility(new BeginningOfCombatTriggeredAbility(new FaceVillainousChoiceOpponentsEffect(choice)));
5758
}
5859

5960
private TheDalekEmperor(final TheDalekEmperor card) {
@@ -66,36 +67,6 @@ public TheDalekEmperor copy() {
6667
}
6768
}
6869

69-
class TheDalekEmperorEffect extends OneShotEffect {
70-
71-
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
72-
Outcome.Sacrifice, new TheDalekEmperorFirstChoice(), new TheDalekEmperorSecondChoice()
73-
);
74-
75-
TheDalekEmperorEffect() {
76-
super(Outcome.Benefit);
77-
staticText = "each opponent " + choice.generateRule();
78-
}
79-
80-
private TheDalekEmperorEffect(final TheDalekEmperorEffect effect) {
81-
super(effect);
82-
}
83-
84-
@Override
85-
public TheDalekEmperorEffect copy() {
86-
return new TheDalekEmperorEffect(this);
87-
}
88-
89-
@Override
90-
public boolean apply(Game game, Ability source) {
91-
for (UUID playerId : game.getOpponents(source.getControllerId())) {
92-
Player player = game.getPlayer(playerId);
93-
choice.faceChoice(player, game, source);
94-
}
95-
return true;
96-
}
97-
}
98-
9970
class TheDalekEmperorFirstChoice extends VillainousChoice {
10071

10172
TheDalekEmperorFirstChoice() {

Mage.Sets/src/mage/sets/DoctorWho.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -803,10 +803,10 @@ private DoctorWho() {
803803
cards.add(new SetCardInfo("Swamp", 201, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
804804
cards.add(new SetCardInfo("Swords to Plowshares", 212, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class, NON_FULL_USE_VARIOUS));
805805
cards.add(new SetCardInfo("Swords to Plowshares", 803, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class, NON_FULL_USE_VARIOUS));
806-
//cards.add(new SetCardInfo("Sycorax Commander", 1036, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
807-
//cards.add(new SetCardInfo("Sycorax Commander", 161, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
808-
//cards.add(new SetCardInfo("Sycorax Commander", 445, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
809-
//cards.add(new SetCardInfo("Sycorax Commander", 766, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
806+
cards.add(new SetCardInfo("Sycorax Commander", 1036, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
807+
cards.add(new SetCardInfo("Sycorax Commander", 161, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
808+
cards.add(new SetCardInfo("Sycorax Commander", 445, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
809+
cards.add(new SetCardInfo("Sycorax Commander", 766, Rarity.RARE, mage.cards.s.SycoraxCommander.class, NON_FULL_USE_VARIOUS));
810810
cards.add(new SetCardInfo("Talisman of Conviction", 247, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class, NON_FULL_USE_VARIOUS));
811811
cards.add(new SetCardInfo("Talisman of Conviction", 838, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class, NON_FULL_USE_VARIOUS));
812812
cards.add(new SetCardInfo("Talisman of Creativity", 248, Rarity.UNCOMMON, mage.cards.t.TalismanOfCreativity.class, NON_FULL_USE_VARIOUS));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package mage.abilities.effects.common;
2+
3+
import mage.abilities.Ability;
4+
import mage.abilities.effects.OneShotEffect;
5+
import mage.choices.FaceVillainousChoice;
6+
import mage.constants.Outcome;
7+
import mage.game.Game;
8+
import mage.players.Player;
9+
10+
import java.util.UUID;
11+
12+
/**
13+
* @author TheElk801
14+
*/
15+
public class FaceVillainousChoiceOpponentsEffect extends OneShotEffect {
16+
17+
private final FaceVillainousChoice choice;
18+
19+
public FaceVillainousChoiceOpponentsEffect(FaceVillainousChoice choice) {
20+
super(Outcome.Benefit);
21+
this.choice = choice;
22+
staticText = "each opponent " + choice.generateRule();
23+
}
24+
25+
private FaceVillainousChoiceOpponentsEffect(final FaceVillainousChoiceOpponentsEffect effect) {
26+
super(effect);
27+
this.choice = effect.choice;
28+
}
29+
30+
@Override
31+
public FaceVillainousChoiceOpponentsEffect copy() {
32+
return new FaceVillainousChoiceOpponentsEffect(this);
33+
}
34+
35+
@Override
36+
public boolean apply(Game game, Ability source) {
37+
for (UUID playerId : game.getOpponents(source.getControllerId())) {
38+
Player player = game.getPlayer(playerId);
39+
if (player != null) {
40+
choice.faceChoice(player, game, source);
41+
}
42+
}
43+
return true;
44+
}
45+
}

0 commit comments

Comments
 (0)