mirror of
https://github.com/correl/mage.git
synced 2025-01-11 19:13:02 +00:00
[STX] Implemented Mavinda, Students' Advocate
This commit is contained in:
parent
6ad67b340a
commit
c408776ad7
4 changed files with 161 additions and 16 deletions
138
Mage.Sets/src/mage/cards/m/MavindaStudentsAdvocate.java
Normal file
138
Mage.Sets/src/mage/cards/m/MavindaStudentsAdvocate.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.CastCardFromGraveyardThenExileItEffect;
|
||||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class MavindaStudentsAdvocate extends CardImpl {
|
||||
|
||||
public MavindaStudentsAdvocate(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.BIRD);
|
||||
this.subtype.add(SubType.ADVISOR);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// {0}: You may cast target instant or sorcery card from your graveyard this turn. If that spell doesn't target a creature you control, it costs {8} more to cast this way. If that spell would be put into your graveyard, exile it instead. Activate only once each turn.
|
||||
Ability ability = new LimitedTimesPerTurnActivatedAbility(
|
||||
Zone.BATTLEFIELD, new MavindaStudentsAdvocateEffect(), new GenericManaCost(0)
|
||||
);
|
||||
ability.addTarget(new TargetCardInYourGraveyard(
|
||||
StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD
|
||||
));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private MavindaStudentsAdvocate(final MavindaStudentsAdvocate card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MavindaStudentsAdvocate copy() {
|
||||
return new MavindaStudentsAdvocate(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MavindaStudentsAdvocateEffect extends CastCardFromGraveyardThenExileItEffect {
|
||||
|
||||
MavindaStudentsAdvocateEffect() {
|
||||
super();
|
||||
staticText = "you may cast target instant or sorcery card from your graveyard this turn. " +
|
||||
"If that spell doesn't target a creature you control, it costs {8} more to cast this way. " +
|
||||
"If that spell would be put into your graveyard, exile it instead";
|
||||
}
|
||||
|
||||
private MavindaStudentsAdvocateEffect(final MavindaStudentsAdvocateEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MavindaStudentsAdvocateEffect copy() {
|
||||
return new MavindaStudentsAdvocateEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
if (!super.apply(game, source)) {
|
||||
return false;
|
||||
}
|
||||
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
game.addEffect(new MavindaStudentsAdvocateCostEffect(card, game), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class MavindaStudentsAdvocateCostEffect extends CostModificationEffectImpl {
|
||||
|
||||
private final MageObjectReference mor;
|
||||
|
||||
MavindaStudentsAdvocateCostEffect(Card card, Game game) {
|
||||
super(Duration.EndOfTurn, Outcome.Benefit, CostModificationType.INCREASE_COST);
|
||||
mor = new MageObjectReference(card, game, 1);
|
||||
}
|
||||
|
||||
private MavindaStudentsAdvocateCostEffect(MavindaStudentsAdvocateCostEffect effect) {
|
||||
super(effect);
|
||||
this.mor = effect.mor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source, Ability abilityToModify) {
|
||||
CardUtil.increaseCost(abilityToModify, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
return abilityToModify instanceof SpellAbility
|
||||
&& abilityToModify.isControlledBy(source.getControllerId())
|
||||
&& mor.refersTo(((SpellAbility) abilityToModify).getCharacteristics(game), game)
|
||||
&& abilityToModify
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(Target::getTargets)
|
||||
.flatMap(Collection::stream)
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(MageObject::isCreature)
|
||||
.map(Controllable::getControllerId)
|
||||
.noneMatch(source::isControlledBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MavindaStudentsAdvocateCostEffect copy() {
|
||||
return new MavindaStudentsAdvocateCostEffect(this);
|
||||
}
|
||||
}
|
|
@ -178,6 +178,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Mascot Exhibition", 5, Rarity.MYTHIC, mage.cards.m.MascotExhibition.class));
|
||||
cards.add(new SetCardInfo("Mascot Interception", 110, Rarity.UNCOMMON, mage.cards.m.MascotInterception.class));
|
||||
cards.add(new SetCardInfo("Master Symmetrist", 138, Rarity.UNCOMMON, mage.cards.m.MasterSymmetrist.class));
|
||||
cards.add(new SetCardInfo("Mavinda, Students' Advocate", 21, Rarity.MYTHIC, mage.cards.m.MavindaStudentsAdvocate.class));
|
||||
cards.add(new SetCardInfo("Mentor's Guidance", 46, Rarity.UNCOMMON, mage.cards.m.MentorsGuidance.class));
|
||||
cards.add(new SetCardInfo("Mercurial Transformation", 47, Rarity.UNCOMMON, mage.cards.m.MercurialTransformation.class));
|
||||
cards.add(new SetCardInfo("Mila, Crafty Companion", 153, Rarity.MYTHIC, mage.cards.m.MilaCraftyCompanion.class));
|
||||
|
|
|
@ -20,7 +20,7 @@ public class CastCardFromGraveyardThenExileItEffect extends OneShotEffect {
|
|||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
CastCardFromGraveyardThenExileItEffect(final CastCardFromGraveyardThenExileItEffect effect) {
|
||||
protected CastCardFromGraveyardThenExileItEffect(final CastCardFromGraveyardThenExileItEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
@ -32,15 +32,15 @@ public class CastCardFromGraveyardThenExileItEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
|
||||
if (card != null) {
|
||||
ContinuousEffect effect = new CastCardFromGraveyardEffect();
|
||||
effect.setTargetPointer(new FixedTarget(card, game));
|
||||
game.addEffect(effect, source);
|
||||
effect = new ExileReplacementEffect(card.getId());
|
||||
game.addEffect(effect, source);
|
||||
return true;
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
ContinuousEffect effect = new CastCardFromGraveyardEffect();
|
||||
effect.setTargetPointer(new FixedTarget(card, game));
|
||||
game.addEffect(effect, source);
|
||||
effect = new ExileReplacementEffect(card.getId());
|
||||
game.addEffect(effect, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ class CastCardFromGraveyardEffect extends AsThoughEffectImpl {
|
|||
this.staticText = "You may cast target card from your graveyard";
|
||||
}
|
||||
|
||||
CastCardFromGraveyardEffect(final CastCardFromGraveyardEffect effect) {
|
||||
private CastCardFromGraveyardEffect(final CastCardFromGraveyardEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,8 @@ class CastCardFromGraveyardEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return objectId.equals(this.getTargetPointer().getFirst(game, source)) && affectedControllerId.equals(source.getControllerId());
|
||||
return objectId.equals(this.getTargetPointer().getFirst(game, source))
|
||||
&& affectedControllerId.equals(source.getControllerId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +82,7 @@ class ExileReplacementEffect extends ReplacementEffectImpl {
|
|||
this.staticText = "If that card would be put into your graveyard this turn, exile it instead";
|
||||
}
|
||||
|
||||
ExileReplacementEffect(final ExileReplacementEffect effect) {
|
||||
private ExileReplacementEffect(final ExileReplacementEffect effect) {
|
||||
super(effect);
|
||||
this.cardId = effect.cardId;
|
||||
}
|
||||
|
@ -95,10 +96,9 @@ class ExileReplacementEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(this.cardId);
|
||||
if (controller != null && card != null) {
|
||||
return controller.moveCards(card, Zone.EXILED, source, game);
|
||||
}
|
||||
return false;
|
||||
return controller != null
|
||||
&& card != null
|
||||
&& controller.moveCards(card, Zone.EXILED, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -114,6 +114,12 @@ public final class StaticFilters {
|
|||
FILTER_CARD_FROM_YOUR_GRAVEYARD.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterCard FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD = new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard");
|
||||
|
||||
static {
|
||||
FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterNoncreatureCard FILTER_CARD_NON_CREATURE = new FilterNoncreatureCard();
|
||||
|
||||
static {
|
||||
|
|
Loading…
Reference in a new issue