mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
Added WinterCynicalOpportunist.java card to the DuskmournHouseOfHorrorCommander set and card.
This commit is contained in:
parent
5b687c344e
commit
56ccfd2630
2 changed files with 221 additions and 6 deletions
220
Mage.Sets/src/mage/cards/w/WinterCynicalOpportunist.java
Normal file
220
Mage.Sets/src/mage/cards/w/WinterCynicalOpportunist.java
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.condition.common.DeliriumCondition;
|
||||
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.MillCardsControllerEffect;
|
||||
import mage.abilities.hint.HintUtils;
|
||||
import mage.abilities.keyword.DeathtouchAbility;
|
||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterPermanentCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lashed
|
||||
*/
|
||||
public final class WinterCynicalOpportunist extends CardImpl {
|
||||
|
||||
public WinterCynicalOpportunist(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}");
|
||||
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WARLOCK);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// Deathtouch
|
||||
this.addAbility(DeathtouchAbility.getInstance());
|
||||
|
||||
// Whenever Winter attacks, mill three cards.
|
||||
this.addAbility(new AttacksTriggeredAbility(new MillCardsControllerEffect(3), false));
|
||||
|
||||
// Delirium -- At the beginning of your end step, you may exile any number of cards from your graveyard with four or more card types among them. If you do, put a permanent card from among them onto the battlefield with a finality counter on it.
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
TargetController.YOU,
|
||||
new WinterCynicalOpportunistDeliriumEffect(),
|
||||
true)
|
||||
.setAbilityWord(AbilityWord.DELIRIUM)
|
||||
.withInterveningIf(DeliriumCondition.instance)
|
||||
.addHint(CardTypesInGraveyardCount.YOU.getHint()));
|
||||
}
|
||||
|
||||
|
||||
private WinterCynicalOpportunist(final WinterCynicalOpportunist card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WinterCynicalOpportunist copy() {
|
||||
return new WinterCynicalOpportunist(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WinterCynicalOpportunistDeliriumEffect extends OneShotEffect {
|
||||
|
||||
public WinterCynicalOpportunistDeliriumEffect() {
|
||||
super(Outcome.PutCardInPlay);
|
||||
this.staticText = "exile any number of cards from your graveyard. " +
|
||||
"If you do, put a permanent card from among them onto the battlefield with a finality counter on it";
|
||||
}
|
||||
|
||||
private WinterCynicalOpportunistDeliriumEffect(final WinterCynicalOpportunistDeliriumEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WinterCynicalOpportunistDeliriumEffect copy() {
|
||||
return new WinterCynicalOpportunistDeliriumEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let the player select cards to exile
|
||||
DeliriumTarget target = new DeliriumTarget();
|
||||
if (!target.canChoose(controller.getId(), source, game) ||
|
||||
!controller.choose(Outcome.Exile, target, source, game)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exile the selected cards
|
||||
Set<Card> cardsToExile = target.getTargets().stream()
|
||||
.map(game::getCard)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (cardsToExile.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
controller.moveCards(cardsToExile, Zone.EXILED, source, game);
|
||||
|
||||
// Filter permanent cards from the exiled cards
|
||||
FilterCard filter = new FilterPermanentCard("permanent card from among the exiled cards to put onto the battlefield");
|
||||
filter.add(new WinterCynicalOpportunistExiledPredicate(cardsToExile));
|
||||
|
||||
TargetCard targetPermanent = new TargetCard(1, 1, Zone.EXILED, filter);
|
||||
Cards permanentCards = new CardsImpl();
|
||||
cardsToExile.stream()
|
||||
.filter(card -> card.isPermanent(game))
|
||||
.forEach(permanentCards::add);
|
||||
|
||||
if (controller.choose(Outcome.PutCardInPlay, permanentCards, targetPermanent, source, game)) {
|
||||
|
||||
Card cardToPut = game.getCard(targetPermanent.getFirstTarget());
|
||||
if (cardToPut != null) {
|
||||
controller.moveCards(cardToPut, Zone.BATTLEFIELD, source, game);
|
||||
|
||||
// Add a finality counter
|
||||
Card permanentCard = game.getPermanent(cardToPut.getId());
|
||||
if (permanentCard != null) {
|
||||
permanentCard.addCounters(CounterType.FINALITY.createInstance(), source.getControllerId(), source, game);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class DeliriumTarget extends TargetCardInYourGraveyard {
|
||||
|
||||
DeliriumTarget() {
|
||||
super(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD, true);
|
||||
this.targetName = "any number of cards from your graveyard";
|
||||
}
|
||||
|
||||
private DeliriumTarget(final DeliriumTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeliriumTarget copy() {
|
||||
return new DeliriumTarget(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(Game game) {
|
||||
String text = "Select " + CardUtil.addArticle(targetName);
|
||||
Set<CardType> types = getCardTypes(this.getTargets(), game);
|
||||
text += " (selected " + this.getTargets().size() + " cards; card types: ";
|
||||
text += HintUtils.prepareText(
|
||||
types.size() + " of 4",
|
||||
types.size() >= 4 ? Color.GREEN : Color.RED
|
||||
);
|
||||
text += " [" + types.stream().map(CardType::toString).collect(Collectors.joining(", ")) + "])";
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosen(Game game) {
|
||||
return super.isChosen(game) && getCardTypesCount(this.getTargets(), game) >= 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
|
||||
if (!super.canChoose(sourceControllerId, source, game)) {
|
||||
return false;
|
||||
}
|
||||
// Check that selecting all the possible cards would have >= 4 different card types
|
||||
return getCardTypesCount(this.possibleTargets(sourceControllerId, source, game), game) >= 4;
|
||||
}
|
||||
|
||||
private static Set<CardType> getCardTypes(Collection<UUID> cardIds, Game game) {
|
||||
return cardIds
|
||||
.stream()
|
||||
.map(game::getCard)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(c -> c.getCardType(game).stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static int getCardTypesCount(Collection<UUID> cardIds, Game game) {
|
||||
return getCardTypes(cardIds, game).size();
|
||||
}
|
||||
}
|
||||
|
||||
class WinterCynicalOpportunistExiledPredicate implements mage.filter.predicate.Predicate<Card> {
|
||||
|
||||
private final Set<Card> exiledCards;
|
||||
|
||||
public WinterCynicalOpportunistExiledPredicate(Set<Card> exiledCards) {
|
||||
this.exiledCards = exiledCards;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Card input, Game game) {
|
||||
return exiledCards.contains(input);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Aesi, Tyrant of Gyre Strait", 210, Rarity.MYTHIC, mage.cards.a.AesiTyrantOfGyreStrait.class));
|
||||
cards.add(new SetCardInfo("Aether Gale", 109, Rarity.RARE, mage.cards.a.AetherGale.class));
|
||||
cards.add(new SetCardInfo("Aminatou's Augury", 71, Rarity.RARE, mage.cards.a.AminatousAugury.class));
|
||||
cards.add(new SetCardInfo("Ancient Cellarspawn", 16, Rarity.RARE, mage.cards.a.AncientCellarspawn.class));
|
||||
cards.add(new SetCardInfo("Arachnogenesis", 169, Rarity.RARE, mage.cards.a.Arachnogenesis.class));
|
||||
cards.add(new SetCardInfo("Arcane Denial", 110, Rarity.COMMON, mage.cards.a.ArcaneDenial.class));
|
||||
cards.add(new SetCardInfo("Arcane Sanctum", 259, Rarity.UNCOMMON, mage.cards.a.ArcaneSanctum.class));
|
||||
|
|
@ -39,7 +38,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Auramancer", 97, Rarity.COMMON, mage.cards.a.Auramancer.class));
|
||||
cards.add(new SetCardInfo("Azorius Chancery", 261, Rarity.UNCOMMON, mage.cards.a.AzoriusChancery.class));
|
||||
cards.add(new SetCardInfo("Azorius Signet", 240, Rarity.UNCOMMON, mage.cards.a.AzoriusSignet.class));
|
||||
cards.add(new SetCardInfo("Barbflare Gremlin", 26, Rarity.RARE, mage.cards.b.BarbflareGremlin.class));
|
||||
cards.add(new SetCardInfo("Barren Moor", 262, Rarity.UNCOMMON, mage.cards.b.BarrenMoor.class));
|
||||
cards.add(new SetCardInfo("Basilisk Collar", 241, Rarity.RARE, mage.cards.b.BasiliskCollar.class));
|
||||
cards.add(new SetCardInfo("Bastion of Remembrance", 131, Rarity.UNCOMMON, mage.cards.b.BastionOfRemembrance.class));
|
||||
|
|
@ -90,7 +88,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Deluge of Doom", 18, Rarity.RARE, mage.cards.d.DelugeOfDoom.class));
|
||||
cards.add(new SetCardInfo("Demolisher Spawn", 31, Rarity.RARE, mage.cards.d.DemolisherSpawn.class));
|
||||
cards.add(new SetCardInfo("Demon of Fate's Design", 137, Rarity.RARE, mage.cards.d.DemonOfFatesDesign.class));
|
||||
cards.add(new SetCardInfo("Demonic Covenant", 19, Rarity.RARE, mage.cards.d.DemonicCovenant.class));
|
||||
cards.add(new SetCardInfo("Diabolic Vision", 87, Rarity.UNCOMMON, mage.cards.d.DiabolicVision.class));
|
||||
cards.add(new SetCardInfo("Dig Through Time", 115, Rarity.RARE, mage.cards.d.DigThroughTime.class));
|
||||
cards.add(new SetCardInfo("Dimir Aqueduct", 270, Rarity.UNCOMMON, mage.cards.d.DimirAqueduct.class));
|
||||
|
|
@ -148,7 +145,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Infernal Grasp", 143, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class));
|
||||
cards.add(new SetCardInfo("Inkshield", 221, Rarity.RARE, mage.cards.i.Inkshield.class));
|
||||
cards.add(new SetCardInfo("Inscription of Abundance", 186, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class));
|
||||
cards.add(new SetCardInfo("Into the Pit", 20, Rarity.RARE, mage.cards.i.IntoThePit.class));
|
||||
cards.add(new SetCardInfo("Ishkanah, Grafwidow", 187, Rarity.MYTHIC, mage.cards.i.IshkanahGrafwidow.class));
|
||||
cards.add(new SetCardInfo("Jungle Hollow", 285, Rarity.COMMON, mage.cards.j.JungleHollow.class));
|
||||
cards.add(new SetCardInfo("Kaervek the Merciless", 222, Rarity.RARE, mage.cards.k.KaervekTheMerciless.class));
|
||||
|
|
@ -222,7 +218,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Rendmaw, Creaking Nest", 5, Rarity.MYTHIC, mage.cards.r.RendmawCreakingNest.class));
|
||||
cards.add(new SetCardInfo("Retreat to Coralhelm", 126, Rarity.UNCOMMON, mage.cards.r.RetreatToCoralhelm.class));
|
||||
cards.add(new SetCardInfo("Return to Dust", 102, Rarity.UNCOMMON, mage.cards.r.ReturnToDust.class));
|
||||
cards.add(new SetCardInfo("Sadistic Shell Game", 24, Rarity.RARE, mage.cards.s.SadisticShellGame.class));
|
||||
cards.add(new SetCardInfo("Sakura-Tribe Elder", 194, Rarity.COMMON, mage.cards.s.SakuraTribeElder.class));
|
||||
cards.add(new SetCardInfo("Sandwurm Convergence", 195, Rarity.RARE, mage.cards.s.SandwurmConvergence.class));
|
||||
cards.add(new SetCardInfo("Scavenging Ooze", 196, Rarity.RARE, mage.cards.s.ScavengingOoze.class));
|
||||
|
|
@ -241,7 +236,6 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Skaab Ruinator", 128, Rarity.MYTHIC, mage.cards.s.SkaabRuinator.class));
|
||||
cards.add(new SetCardInfo("Skola Grovedancer", 199, Rarity.COMMON, mage.cards.s.SkolaGrovedancer.class));
|
||||
cards.add(new SetCardInfo("Smoldering Marsh", 299, Rarity.RARE, mage.cards.s.SmolderingMarsh.class));
|
||||
cards.add(new SetCardInfo("Soaring Lightbringer", 11, Rarity.RARE, mage.cards.s.SoaringLightbringer.class));
|
||||
cards.add(new SetCardInfo("Sol Ring", 94, Rarity.UNCOMMON, mage.cards.s.SolRing.class));
|
||||
cards.add(new SetCardInfo("Solemn Simulacrum", 253, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class));
|
||||
cards.add(new SetCardInfo("Sphere of Safety", 104, Rarity.UNCOMMON, mage.cards.s.SphereOfSafety.class));
|
||||
|
|
@ -310,6 +304,7 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Whispersilk Cloak", 257, Rarity.UNCOMMON, mage.cards.w.WhispersilkCloak.class));
|
||||
cards.add(new SetCardInfo("Whisperwood Elemental", 204, Rarity.MYTHIC, mage.cards.w.WhisperwoodElemental.class));
|
||||
cards.add(new SetCardInfo("Wilderness Reclamation", 205, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class));
|
||||
cards.add(new SetCardInfo("Winter, Cynical Opportunist", 7, Rarity.MYTHIC, mage.cards.w.WinterCynicalOpportunist.class));
|
||||
cards.add(new SetCardInfo("Witch's Clinic", 325, Rarity.RARE, mage.cards.w.WitchsClinic.class));
|
||||
cards.add(new SetCardInfo("Woodland Cemetery", 326, Rarity.RARE, mage.cards.w.WoodlandCemetery.class));
|
||||
cards.add(new SetCardInfo("Worldspine Wurm", 206, Rarity.MYTHIC, mage.cards.w.WorldspineWurm.class));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue