mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Merge pull request #7278 from weirddan455/kaya
[KHM] Implemented Kaya the Inexorable
This commit is contained in:
commit
9c83b3bc11
4 changed files with 276 additions and 0 deletions
170
Mage.Sets/src/mage/cards/k/KayaTheInexorable.java
Normal file
170
Mage.Sets/src/mage/cards/k/KayaTheInexorable.java
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
package mage.cards.k;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.MageObjectReference;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.LoyaltyAbility;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.abilities.effects.common.ExileTargetEffect;
|
||||||
|
import mage.abilities.effects.common.GetEmblemEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.permanent.TokenPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.command.emblems.KayaTheInexorableEmblem;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.ZoneChangeEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.permanent.token.SpiritWhiteToken;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.target.common.TargetNonlandPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author weirddan455
|
||||||
|
*/
|
||||||
|
public final class KayaTheInexorable extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature");
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.not(TokenPredicate.instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public KayaTheInexorable(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{B}");
|
||||||
|
|
||||||
|
this.addSuperType(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.KAYA);
|
||||||
|
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
|
||||||
|
|
||||||
|
// +1: Put a ghostform counter on up to one target nontoken creature. It gains "When this creature dies or is put into exile, return it to its owner's hand and create a 1/1 white Spirit creature token with flying."
|
||||||
|
LoyaltyAbility ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.GHOSTFORM.createInstance()), 1);
|
||||||
|
ability.addEffect(new GainAbilityTargetEffect(new KayaTheInexorableTriggeredAbility(), Duration.WhileOnBattlefield,
|
||||||
|
"It gains \"When this creature dies or is put into exile, return it to its owner's hand and create a 1/1 white Spirit creature token with flying.\""));
|
||||||
|
ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false));
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// −3: Exile target nonland permanent.
|
||||||
|
ability = new LoyaltyAbility(new ExileTargetEffect(), -3);
|
||||||
|
ability.addTarget(new TargetNonlandPermanent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// −7: You get an emblem with "At the beginning of your upkeep, you may cast a legendary spell from your hand, from your graveyard, or from among cards you own in exile without paying its mana cost."
|
||||||
|
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KayaTheInexorableEmblem()), -7));
|
||||||
|
}
|
||||||
|
|
||||||
|
private KayaTheInexorable(final KayaTheInexorable card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KayaTheInexorable copy() {
|
||||||
|
return new KayaTheInexorable(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KayaTheInexorableTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
public KayaTheInexorableTriggeredAbility() {
|
||||||
|
super(Zone.ALL, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private KayaTheInexorableTriggeredAbility(KayaTheInexorableTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
||||||
|
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||||
|
return zEvent.getFromZone() == Zone.BATTLEFIELD
|
||||||
|
&& (zEvent.getToZone() == Zone.GRAVEYARD
|
||||||
|
|| zEvent.getToZone() == Zone.EXILED);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||||
|
if (zEvent.getTargetId().equals(this.getSourceId())) {
|
||||||
|
this.getEffects().clear();
|
||||||
|
this.addEffect(new KayaTheInexorableEffect(new MageObjectReference(zEvent.getTarget(), game)));
|
||||||
|
this.addEffect(new CreateTokenEffect(new SpiritWhiteToken()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
Permanent sourcePermanent = null;
|
||||||
|
if (game.getState().getZone(getSourceId()) == Zone.BATTLEFIELD) {
|
||||||
|
sourcePermanent = game.getPermanent(getSourceId());
|
||||||
|
} else {
|
||||||
|
if (game.getShortLivingLKI(getSourceId(), Zone.BATTLEFIELD)) {
|
||||||
|
sourcePermanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sourcePermanent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return hasSourceObjectAbility(game, sourcePermanent, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KayaTheInexorableTriggeredAbility copy() {
|
||||||
|
return new KayaTheInexorableTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "When {this} dies or is put into exile, return it to its owner's hand and create a 1/1 white Spirit creature token with flying.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KayaTheInexorableEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private final MageObjectReference mor;
|
||||||
|
|
||||||
|
KayaTheInexorableEffect(MageObjectReference mor) {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.mor = mor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KayaTheInexorableEffect(KayaTheInexorableEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.mor = effect.mor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KayaTheInexorableEffect copy() {
|
||||||
|
return new KayaTheInexorableEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card card = game.getCard(mor.getSourceId());
|
||||||
|
if (card == null || card.getZoneChangeCounter(game) - 1 != mor.getZoneChangeCounter()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return player.moveCards(card, Zone.HAND, source, game);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ public final class Kaldheim extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Gilded Assault Cart", 390, Rarity.UNCOMMON, mage.cards.g.GildedAssaultCart.class));
|
cards.add(new SetCardInfo("Gilded Assault Cart", 390, Rarity.UNCOMMON, mage.cards.g.GildedAssaultCart.class));
|
||||||
cards.add(new SetCardInfo("Gladewalker Ritualist", 392, Rarity.UNCOMMON, mage.cards.g.GladewalkerRitualist.class));
|
cards.add(new SetCardInfo("Gladewalker Ritualist", 392, Rarity.UNCOMMON, mage.cards.g.GladewalkerRitualist.class));
|
||||||
cards.add(new SetCardInfo("Hengegate Pathway", 260, Rarity.RARE, mage.cards.h.HengegatePathway.class));
|
cards.add(new SetCardInfo("Hengegate Pathway", 260, Rarity.RARE, mage.cards.h.HengegatePathway.class));
|
||||||
|
cards.add(new SetCardInfo("Kaya the Inexorable", 218, Rarity.MYTHIC, mage.cards.k.KayaTheInexorable.class));
|
||||||
cards.add(new SetCardInfo("Rampage of the Valkyries", 393, Rarity.UNCOMMON, mage.cards.r.RampageOfTheValkyries.class));
|
cards.add(new SetCardInfo("Rampage of the Valkyries", 393, Rarity.UNCOMMON, mage.cards.r.RampageOfTheValkyries.class));
|
||||||
cards.add(new SetCardInfo("Realmwalker", 188, Rarity.RARE, mage.cards.r.Realmwalker.class));
|
cards.add(new SetCardInfo("Realmwalker", 188, Rarity.RARE, mage.cards.r.Realmwalker.class));
|
||||||
cards.add(new SetCardInfo("Renegade Reaper", 386, Rarity.UNCOMMON, mage.cards.r.RenegadeReaper.class));
|
cards.add(new SetCardInfo("Renegade Reaper", 386, Rarity.UNCOMMON, mage.cards.r.RenegadeReaper.class));
|
||||||
|
|
|
@ -64,6 +64,7 @@ public enum CounterType {
|
||||||
FUNGUS("fungus"),
|
FUNGUS("fungus"),
|
||||||
FUSE("fuse"),
|
FUSE("fuse"),
|
||||||
GEM("gem"),
|
GEM("gem"),
|
||||||
|
GHOSTFORM("ghostform"),
|
||||||
GLOBE("globe"),
|
GLOBE("globe"),
|
||||||
GLYPH("glyph"),
|
GLYPH("glyph"),
|
||||||
GOLD("gold"),
|
GOLD("gold"),
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package mage.game.command.emblems;
|
||||||
|
|
||||||
|
import mage.ApprovingObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.choices.Choice;
|
||||||
|
import mage.choices.ChoiceImpl;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.filter.common.FilterOwnedCard;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.command.Emblem;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetCard;
|
||||||
|
import mage.target.common.TargetCardInExile;
|
||||||
|
import mage.target.common.TargetCardInHand;
|
||||||
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author weirddan455
|
||||||
|
*/
|
||||||
|
public class KayaTheInexorableEmblem extends Emblem {
|
||||||
|
|
||||||
|
// −7: You get an emblem with "At the beginning of your upkeep, you may cast a legendary spell from your hand, from your graveyard, or from among cards you own in exile without paying its mana cost."
|
||||||
|
public KayaTheInexorableEmblem() {
|
||||||
|
|
||||||
|
this.setName("Emblem Kaya");
|
||||||
|
this.setExpansionSetCodeForImage("KHM");
|
||||||
|
this.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, new KayaTheInexorableEmblemEffect(), TargetController.YOU, true, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KayaTheInexorableEmblemEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private static final FilterOwnedCard filter = new FilterOwnedCard();
|
||||||
|
private static final Set<String> choices = new LinkedHashSet<>();
|
||||||
|
static {
|
||||||
|
filter.add(SuperType.LEGENDARY.getPredicate());
|
||||||
|
filter.add(Predicates.not(CardType.LAND.getPredicate()));
|
||||||
|
choices.add("Hand");
|
||||||
|
choices.add("Graveyard");
|
||||||
|
choices.add("Exile");
|
||||||
|
}
|
||||||
|
|
||||||
|
public KayaTheInexorableEmblemEffect() {
|
||||||
|
super(Outcome.PlayForFree);
|
||||||
|
this.staticText = "cast a legendary spell from your hand, from your graveyard, or from among cards you own in exile without paying its mana cost";
|
||||||
|
}
|
||||||
|
|
||||||
|
private KayaTheInexorableEmblemEffect(final KayaTheInexorableEmblemEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KayaTheInexorableEmblemEffect copy() {
|
||||||
|
return new KayaTheInexorableEmblemEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player != null) {
|
||||||
|
Choice zoneChoice = new ChoiceImpl(true);
|
||||||
|
zoneChoice.setMessage("Cast a legendary spell from hand, graveyard, or exile");
|
||||||
|
zoneChoice.setChoices(choices);
|
||||||
|
zoneChoice.clearChoice();
|
||||||
|
if (player.choose(Outcome.PlayForFree, zoneChoice, game)) {
|
||||||
|
TargetCard target = null;
|
||||||
|
switch (zoneChoice.getChoice()) {
|
||||||
|
case "Hand":
|
||||||
|
target = new TargetCardInHand(0, 1, filter);
|
||||||
|
target.setTargetName("legendary spell from your hand");
|
||||||
|
break;
|
||||||
|
case "Graveyard":
|
||||||
|
target = new TargetCardInYourGraveyard(0, 1, filter, true);
|
||||||
|
target.setTargetName("legendary spell from your graveyard");
|
||||||
|
break;
|
||||||
|
case "Exile":
|
||||||
|
target = new TargetCardInExile(0, 1, filter, null, true);
|
||||||
|
target.setNotTarget(true);
|
||||||
|
target.setTargetName("legendary spell you own in exile");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (target != null && player.chooseTarget(Outcome.PlayForFree, target, source, game)) {
|
||||||
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
|
if (card != null) {
|
||||||
|
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
|
||||||
|
boolean cardWasCast = player.cast(player.chooseAbilityForCast(card, game, true),
|
||||||
|
game, true, new ApprovingObject(source, game));
|
||||||
|
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
|
||||||
|
return cardWasCast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue