mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
[STX] Implemented Manifestation Sage
This commit is contained in:
parent
8996daeb82
commit
b6ca0ca222
6 changed files with 187 additions and 108 deletions
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KianneDeanOfSubstanceValue copy() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
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 += ')';
|
||||
}
|
||||
for (UUID tokenId : token.getLastAddedTokenIds()) {
|
||||
Permanent permanent = game.getPermanent(tokenId);
|
||||
if (permanent == null) {
|
||||
continue;
|
||||
}
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(exileCount), source.getControllerId(), source, game);
|
||||
}
|
||||
return true;
|
||||
return "Mana values of cards exiled with study counters: " + message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KianneDeanOfSubstanceHint copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
42
Mage.Sets/src/mage/cards/m/ManifestationSage.java
Normal file
42
Mage.Sets/src/mage/cards/m/ManifestationSage.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue