Merge pull request #7278 from weirddan455/kaya

[KHM] Implemented Kaya the Inexorable
This commit is contained in:
Oleg Agafonov 2020-12-27 12:22:24 +01:00 committed by GitHub
commit 9c83b3bc11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 276 additions and 0 deletions

View 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);
}
}

View file

@ -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("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("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("Realmwalker", 188, Rarity.RARE, mage.cards.r.Realmwalker.class));
cards.add(new SetCardInfo("Renegade Reaper", 386, Rarity.UNCOMMON, mage.cards.r.RenegadeReaper.class));

View file

@ -64,6 +64,7 @@ public enum CounterType {
FUNGUS("fungus"),
FUSE("fuse"),
GEM("gem"),
GHOSTFORM("ghostform"),
GLOBE("globe"),
GLYPH("glyph"),
GOLD("gold"),

View file

@ -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;
}
}