[STX] Implemented Manifestation Sage

This commit is contained in:
Evan Kranzler 2021-04-01 07:49:10 -04:00
parent 8996daeb82
commit b6ca0ca222
6 changed files with 187 additions and 108 deletions

View file

@ -13,15 +13,13 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.filter.predicate.mageobject.SharesColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.FractalToken;
import mage.game.permanent.token.Token;
import mage.game.permanent.token.QuandrixToken;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@ -48,7 +46,9 @@ public final class KasminaEnigmaSage extends CardImpl {
this.addAbility(new LoyaltyAbility(new ScryEffect(1), 2));
// X: Create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it.
this.addAbility(new LoyaltyAbility(new KasminaEnigmaSageTokenEffect()));
this.addAbility(new LoyaltyAbility(QuandrixToken.getEffect(
GetXLoyaltyValue.instance, "Put X +1/+1 counters on it"
)));
// 8: Search your library for an instant or sorcery card that shares a color with this planeswalker, exile that card, then shuffle. You may cast that card without paying its mana cost.
this.addAbility(new LoyaltyAbility(new KasminaEnigmaSageSearchEffect(), -8));
@ -106,40 +106,6 @@ class KasminaEnigmaSageGainAbilitiesEffect extends ContinuousEffectImpl {
}
}
class KasminaEnigmaSageTokenEffect extends OneShotEffect {
KasminaEnigmaSageTokenEffect() {
super(Outcome.Benefit);
staticText = "create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it";
}
private KasminaEnigmaSageTokenEffect(final KasminaEnigmaSageTokenEffect effect) {
super(effect);
}
@Override
public KasminaEnigmaSageTokenEffect copy() {
return new KasminaEnigmaSageTokenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new FractalToken();
token.putOntoBattlefield(1, game, source, source.getControllerId());
int loyalty = GetXLoyaltyValue.instance.calculate(game, source, this);
if (loyalty < 1) {
return true;
}
for (UUID tokenId : token.getLastAddedTokenIds()) {
Permanent permanent = game.getPermanent(tokenId);
if (permanent != null) {
permanent.addCounters(CounterType.P1P1.createInstance(loyalty), source.getControllerId(), source, game);
}
}
return true;
}
}
class KasminaEnigmaSageSearchEffect extends OneShotEffect {
KasminaEnigmaSageSearchEffect() {

View file

@ -5,7 +5,10 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.*;
import mage.constants.*;
@ -13,15 +16,15 @@ import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterOwnedCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.FractalToken;
import mage.game.permanent.token.Token;
import mage.game.permanent.token.QuandrixToken;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInExile;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
@ -45,9 +48,10 @@ public final class KianneDeanOfSubstance extends ModalDoubleFacesCard {
));
// {4}{G}: Create a 0/0 green and blue Fractal creature token. Put a +1/+1 counter on it for each different mana value among nonland cards you own in exile with study counters on them.
this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(
new KianneDeanOfSubstanceTokenEffect(), new ManaCostsImpl("{4}{G}")
));
this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(QuandrixToken.getEffect(
KianneDeanOfSubstanceValue.instance, "Put a +1/+1 counter on it for each different mana value " +
"among nonland cards you own in exile with study counters on them"
), new ManaCostsImpl("{4}{G}")).addHint(KianneDeanOfSubstanceHint.instance));
// 2.
// Imbraham, Dean of Theory
@ -114,48 +118,62 @@ class KianneDeanOfSubstanceExileEffect extends OneShotEffect {
}
}
class KianneDeanOfSubstanceTokenEffect extends OneShotEffect {
KianneDeanOfSubstanceTokenEffect() {
super(Outcome.Benefit);
staticText = "create a 0/0 green and blue Fractal creature token. Put a +1/+1 counter on it " +
"for each different mana value among nonland cards you own in exile with study counters on them";
}
private KianneDeanOfSubstanceTokenEffect(final KianneDeanOfSubstanceTokenEffect effect) {
super(effect);
}
enum KianneDeanOfSubstanceValue implements DynamicValue {
instance;
@Override
public KianneDeanOfSubstanceTokenEffect copy() {
return new KianneDeanOfSubstanceTokenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new FractalToken();
token.putOntoBattlefield(1, game, source, source.getControllerId());
int exileCount = game
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game
.getExile()
.getAllCards(game)
.stream()
.filter(Objects::nonNull)
.filter(card -> card.isOwnedBy(source.getControllerId()))
.filter(card -> card.isOwnedBy(sourceAbility.getControllerId()))
.filter(card -> card.getCounters(game).containsKey(CounterType.STUDY))
.map(MageObject::getConvertedManaCost)
.distinct()
.mapToInt(x -> 1)
.sum();
if (exileCount < 1) {
return true;
}
for (UUID tokenId : token.getLastAddedTokenIds()) {
Permanent permanent = game.getPermanent(tokenId);
if (permanent == null) {
continue;
@Override
public KianneDeanOfSubstanceValue copy() {
return instance;
}
permanent.addCounters(CounterType.P1P1.createInstance(exileCount), source.getControllerId(), source, game);
@Override
public String getMessage() {
return "";
}
return true;
}
enum KianneDeanOfSubstanceHint implements Hint {
instance;
@Override
public String getText(Game game, Ability ability) {
List<Integer> values = game.getExile()
.getAllCards(game)
.stream()
.filter(Objects::nonNull)
.filter(card -> card.isOwnedBy(ability.getControllerId()))
.filter(card -> card.getCounters(game).containsKey(CounterType.STUDY))
.map(MageObject::getConvertedManaCost)
.distinct()
.sorted()
.collect(Collectors.toList());
String message = "" + values.size();
if (values.size() > 0) {
message += " (";
message += values.stream().map(i -> "" + i).reduce((a, b) -> a + ", " + b).orElse("");
message += ')';
}
return "Mana values of cards exiled with study counters: " + message;
}
@Override
public KianneDeanOfSubstanceHint copy() {
return instance;
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.permanent.token.QuandrixToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ManifestationSage extends CardImpl {
public ManifestationSage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G/U}{G/U}{G/U}{G/U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Manifestation Sage enters the battlefield, create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it, where X is the number of cards in your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(QuandrixToken.getEffect(
CardsInControllerHandCount.instance, "Put X +1/+1 counters on it, " +
"where X is the number of cards in your hand"
)));
}
private ManifestationSage(final ManifestationSage card) {
super(card);
}
@Override
public ManifestationSage copy() {
return new ManifestationSage(this);
}
}

View file

@ -83,6 +83,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet {
cards.add(new SetCardInfo("Lorehold Pledgemage", 201, Rarity.COMMON, mage.cards.l.LoreholdPledgemage.class));
cards.add(new SetCardInfo("Mage Hunter", 76, Rarity.UNCOMMON, mage.cards.m.MageHunter.class));
cards.add(new SetCardInfo("Magma Opus", 203, Rarity.MYTHIC, mage.cards.m.MagmaOpus.class));
cards.add(new SetCardInfo("Manifestation Sage", 205, Rarity.RARE, mage.cards.m.ManifestationSage.class));
cards.add(new SetCardInfo("Mountain", 372, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Multiple Choice", 48, Rarity.RARE, mage.cards.m.MultipleChoice.class));
cards.add(new SetCardInfo("Necroblossom Snarl", 269, Rarity.RARE, mage.cards.n.NecroblossomSnarl.class));

View file

@ -1,33 +0,0 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.Arrays;
/**
* @author TheElk801
*/
public final class FractalToken extends TokenImpl {
public FractalToken() {
super("Fractal", "0/0 green and blue Fractal creature token");
cardType.add(CardType.CREATURE);
subtype.add(SubType.FRACTAL);
color.setGreen(true);
color.setBlue(true);
power = new MageInt(0);
toughness = new MageInt(0);
availableImageSetCodes = Arrays.asList("STX");
}
private FractalToken(final FractalToken token) {
super(token);
}
public FractalToken copy() {
return new FractalToken(this);
}
}

View file

@ -0,0 +1,85 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.Arrays;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class QuandrixToken extends TokenImpl {
public QuandrixToken() {
super("Fractal", "0/0 green and blue Fractal creature token");
cardType.add(CardType.CREATURE);
subtype.add(SubType.FRACTAL);
color.setGreen(true);
color.setBlue(true);
power = new MageInt(0);
toughness = new MageInt(0);
availableImageSetCodes = Arrays.asList("STX");
}
private QuandrixToken(final QuandrixToken token) {
super(token);
}
public QuandrixToken copy() {
return new QuandrixToken(this);
}
public static QuandrixTokenEffect getEffect(DynamicValue xValue, String text) {
return new QuandrixTokenEffect(xValue, text);
}
private static final class QuandrixTokenEffect extends OneShotEffect {
private final DynamicValue xValue;
private QuandrixTokenEffect(DynamicValue xValue, String text) {
super(Outcome.Benefit);
this.xValue = xValue;
this.staticText = "create a 0/0 green and blue Fractal creature token. " + text;
}
private QuandrixTokenEffect(final QuandrixTokenEffect effect) {
super(effect);
this.xValue = effect.xValue;
}
@Override
public QuandrixTokenEffect copy() {
return new QuandrixTokenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new QuandrixToken();
token.putOntoBattlefield(1, game, source, source.getControllerId());
int value = xValue.calculate(game, source, this);
if (value < 1) {
return true;
}
for (UUID tokenId : token.getLastAddedTokenIds()) {
Permanent permanent = game.getPermanent(tokenId);
if (permanent == null) {
continue;
}
permanent.addCounters(CounterType.P1P1.createInstance(value), source.getControllerId(), source, game);
}
return true;
}
}
}