- [KHM] Added Valki, God of Lies

This commit is contained in:
jeffwadsworth 2021-01-18 18:02:48 -06:00
parent 6ea54aec8b
commit b750bb93d5
3 changed files with 436 additions and 0 deletions

View file

@ -0,0 +1,353 @@
package mage.cards.v;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CopyEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.cards.Card;
import mage.cards.ModalDoubleFacesCard;
import mage.constants.*;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.command.emblems.TibaltCosmicImposterEmblem;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInExile;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author jeffwadsworth
*/
public final class ValkiGodOfLies extends ModalDoubleFacesCard {
public ValkiGodOfLies(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{1}{B}",
"Tibalt, Cosmic Imposter", new CardType[]{CardType.PLANESWALKER}, new SubType[]{}, "{5}{B}{R}"
);
// 1.
// Valki, God of Lies
// Legendary Creature - God
this.getLeftHalfCard().addSuperType(SuperType.LEGENDARY);
this.getLeftHalfCard().setPT(new MageInt(2), new MageInt(1));
// When Valki enters the battlefield, each opponent reveals their hand. For each opponent, exile a creature card they revealed this way until Valki leaves the battlefield.
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new ValkiGodOfLiesRevealExileEffect()));
// X: Choose a creature card exiled with Valki with converted mana cost X. Valki becomes a copy of that card.
this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ValkiGodOfLiesCopyExiledEffect(), new ManaCostsImpl("{X}")));
// 2.
// Tibalt, Cosmic Imposter
// Legendary Planeswalker
this.getRightHalfCard().addSuperType(SuperType.LEGENDARY);
// this errors out right now. of course, we need to add the Tibalt subtype to this object
//this.getRightHalfCard().addSubType(game, SubType.TIBALT);
this.getRightHalfCard().addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// As Tibalt enters the battlefield, you get an emblem with You may play cards exiled with Tibalt, Cosmic Impostor, and you may spend mana as though it were mana of any color to cast those spells.
this.getRightHalfCard().addAbility(new AsEntersBattlefieldAbility(new GetEmblemEffect(new TibaltCosmicImposterEmblem())));
// +2: Exile the top card of each players library.
this.getRightHalfCard().addAbility(new LoyaltyAbility(new ExileTopCardEachPlayersLibrary(), 2));
// 3: Exile target artifact or creature.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new ExileTargetArtifactOrCreatureEffect(), -3);
loyaltyAbility.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
this.getRightHalfCard().addAbility(loyaltyAbility);
// 8: Exile all cards from all graveyards. Add {R}{R}{R}.
this.getRightHalfCard().addAbility(new LoyaltyAbility(new ExileAllCardsFromAllGraveyards(), -8));
}
private ValkiGodOfLies(final ValkiGodOfLies card) {
super(card);
}
@Override
public ValkiGodOfLies copy() {
return new ValkiGodOfLies(this);
}
}
class ValkiGodOfLiesRevealExileEffect extends OneShotEffect {
ValkiGodOfLiesRevealExileEffect() {
super(Outcome.Benefit);
staticText = "each opponent reveals their hand. For each opponent, exile a creature card they revealed this way until Valki leaves the battlefield.";
}
private ValkiGodOfLiesRevealExileEffect(final ValkiGodOfLiesRevealExileEffect effect) {
super(effect);
}
@Override
public ValkiGodOfLiesRevealExileEffect copy() {
return new ValkiGodOfLiesRevealExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject Valki = game.getObject(source.getSourceId());
if (controller != null
&& Valki != null) {
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + Valki.getZoneChangeCounter(game), game);
for (UUID opponentId : game.getOpponents(controller.getId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
opponent.revealCards(source, opponent.getHand(), game);
TargetCard targetToExile = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_CREATURE);
targetToExile.setNotTarget(true);
if (controller.choose(Outcome.Exile, opponent.getHand(), targetToExile, game)) {
Card targetedCardToExile = game.getCard(targetToExile.getFirstTarget());
if (targetedCardToExile != null
&& game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
controller.moveCardsToExile(targetedCardToExile, source, game, true, exileId, Valki.getName());
}
}
}
}
game.addDelayedTriggeredAbility(new ValkiGodOfLiesReturnExiledCardAbility(), source);
return true;
}
return false;
}
}
class ValkiGodOfLiesReturnExiledCardAbility extends DelayedTriggeredAbility {
public ValkiGodOfLiesReturnExiledCardAbility() {
super(new ValkiGodOfLiesReturnExiledCardEffect(), Duration.OneUse);
this.usesStack = false;
this.setRuleVisible(false);
}
public ValkiGodOfLiesReturnExiledCardAbility(final ValkiGodOfLiesReturnExiledCardAbility ability) {
super(ability);
}
@Override
public ValkiGodOfLiesReturnExiledCardAbility copy() {
return new ValkiGodOfLiesReturnExiledCardAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(this.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
return true;
}
}
return false;
}
}
class ValkiGodOfLiesReturnExiledCardEffect extends OneShotEffect {
public ValkiGodOfLiesReturnExiledCardEffect() {
super(Outcome.Benefit);
this.staticText = "Return exiled card to its owner's hand";
}
public ValkiGodOfLiesReturnExiledCardEffect(final ValkiGodOfLiesReturnExiledCardEffect effect) {
super(effect);
}
@Override
public ValkiGodOfLiesReturnExiledCardEffect copy() {
return new ValkiGodOfLiesReturnExiledCardEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject Valki = game.getObject(source.getSourceId());
if (Valki != null
&& controller != null) {
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + (Valki.getZoneChangeCounter(game) - 1), game);
ExileZone exile = game.getExile().getExileZone(exileId);
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (exile != null
&& sourcePermanent != null) {
controller.moveCards(exile, Zone.HAND, source, game);
return true;
}
}
return false;
}
}
class ValkiGodOfLiesCopyExiledEffect extends OneShotEffect {
public ValkiGodOfLiesCopyExiledEffect() {
super(Outcome.Benefit);
this.staticText = "Choose a creature card exiled with Valki with converted mana cost X. Valki becomes a copy of that card.";
}
public ValkiGodOfLiesCopyExiledEffect(final ValkiGodOfLiesCopyExiledEffect effect) {
super(effect);
}
@Override
public ValkiGodOfLiesCopyExiledEffect copy() {
return new ValkiGodOfLiesCopyExiledEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
MageObject Valki = game.getObject(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null
&& Valki != null) {
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + (Valki.getZoneChangeCounter(game)), game);
FilterCard filter = new FilterCard();
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, source.getManaCostsToPay().getX()));
TargetCardInExile target = new TargetCardInExile(filter, exileId);
Cards cards = game.getExile().getExileZone(exileId);
if (!cards.isEmpty()
&& controller.choose(Outcome.Benefit, cards, target, game)) {
Card chosenExiledCreature = game.getCard(target.getFirstTarget());
if (chosenExiledCreature != null) {
ContinuousEffect copyEffect = new CopyEffect(Duration.WhileOnBattlefield, chosenExiledCreature.getMainCard(), source.getSourceId());
copyEffect.setTargetPointer(new FixedTarget(Valki.getId()));
game.addEffect(copyEffect, source);
return true;
}
}
}
return false;
}
}
class ExileTopCardEachPlayersLibrary extends OneShotEffect {
public ExileTopCardEachPlayersLibrary() {
super(Outcome.Benefit);
this.staticText = "Exile the top card of each players library";
}
public ExileTopCardEachPlayersLibrary(final ExileTopCardEachPlayersLibrary effect) {
super(effect);
}
@Override
public ExileTopCardEachPlayersLibrary copy() {
return new ExileTopCardEachPlayersLibrary(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString(), game);
if (controller != null) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Card topCard = player.getLibrary().getFromTop(game);
controller.moveCardsToExile(topCard, source, game, true, exileId, "Tibalt, Cosmic Imposter");
}
}
return true;
}
return false;
}
}
class ExileTargetArtifactOrCreatureEffect extends OneShotEffect {
public ExileTargetArtifactOrCreatureEffect() {
super(Outcome.Detriment);
this.staticText = "Exile target artifact or creature";
}
public ExileTargetArtifactOrCreatureEffect(final ExileTargetArtifactOrCreatureEffect effect) {
super(effect);
}
@Override
public ExileTargetArtifactOrCreatureEffect copy() {
return new ExileTargetArtifactOrCreatureEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString(), game);
if (controller != null) {
Permanent targetCreatureOrArtifact = game.getPermanent(source.getTargets().getFirstTarget());
if (targetCreatureOrArtifact != null) {
controller.moveCardsToExile(targetCreatureOrArtifact, source, game, true, exileId, "Tibalt, Cosmic Imposter");
return true;
}
}
return false;
}
}
class ExileAllCardsFromAllGraveyards extends OneShotEffect {
public ExileAllCardsFromAllGraveyards() {
super(Outcome.Benefit);
this.staticText = "Exile all cards from all graveyards. Add {R}{R}{R}";
}
public ExileAllCardsFromAllGraveyards(final ExileAllCardsFromAllGraveyards effect) {
super(effect);
}
@Override
public ExileAllCardsFromAllGraveyards copy() {
return new ExileAllCardsFromAllGraveyards(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString(), game);
if (controller != null) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Set<Card> cardsInGraveyard = player.getGraveyard().getCards(game);
controller.moveCardsToExile(cardsInGraveyard, source, game, true, exileId, "Tibalt, Cosmic Imposter");
}
}
controller.getManaPool().addMana(Mana.RedMana(3), game, source); // add {R}{R}{R}
return true;
}
return false;
}
}

View file

@ -277,6 +277,7 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Tyvar Kell", 198, Rarity.MYTHIC, mage.cards.t.TyvarKell.class));
cards.add(new SetCardInfo("Undersea Invader", 78, Rarity.COMMON, mage.cards.u.UnderseaInvader.class));
cards.add(new SetCardInfo("Usher of the Fallen", 35, Rarity.UNCOMMON, mage.cards.u.UsherOfTheFallen.class));
cards.add(new SetCardInfo("Valki, God of Lies", 114, Rarity.MYTHIC, mage.cards.v.ValkiGodOfLies.class));
cards.add(new SetCardInfo("Valkyrie Harbinger", 374, Rarity.RARE, mage.cards.v.ValkyrieHarbinger.class));
cards.add(new SetCardInfo("Valkyrie's Sword", 36, Rarity.UNCOMMON, mage.cards.v.ValkyriesSword.class));
cards.add(new SetCardInfo("Varragoth, Bloodsky Sire", 115, Rarity.RARE, mage.cards.v.VarragothBloodskySire.class));

View file

@ -0,0 +1,82 @@
package mage.game.command.emblems;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.cards.Card;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.command.Emblem;
import mage.util.CardUtil;
/**
*
* @author jeffwadsworth
*/
public final class TibaltCosmicImposterEmblem extends Emblem {
// You may play cards exiled with Tibalt, Cosmic Impostor, and you may spend mana as though it were mana of any color to cast those spells."
public TibaltCosmicImposterEmblem() {
setName("Emblem Tibalt Cosmic Imposter");
this.setExpansionSetCodeForImage("KHM");
Ability ability = new SimpleStaticAbility(Zone.COMMAND, new TibaltCosmicImposterPlayFromExileEffect());
this.getAbilities().add(ability);
}
}
class TibaltCosmicImposterPlayFromExileEffect extends AsThoughEffectImpl {
TibaltCosmicImposterPlayFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may play cards exiled with Tibalt, Cosmic Impostor, and you may spend mana as though it were mana of any color to cast those spells";
}
TibaltCosmicImposterPlayFromExileEffect(final TibaltCosmicImposterPlayFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public TibaltCosmicImposterPlayFromExileEffect copy() {
return new TibaltCosmicImposterPlayFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Emblem tibaltEmblem = (Emblem) game.getEmblem(source.getSourceId());
if (tibaltEmblem == null) {
return false;
}
UUID exileId = CardUtil.getExileZoneId(tibaltEmblem.getSourceObject().getId().toString(), game);
if (exileId == null) {
return false;
}
ExileZone exile = game.getState().getExile().getExileZone(exileId);
if (exile == null) {
return false;
}
if (exile.isEmpty()) {
return false;
}
Card cardInExile = game.getCard(objectId);
if (cardInExile == null) {
return false;
}
if (exile.contains(cardInExile.getId())
&& affectedControllerId.equals(source.getControllerId())
&& game.getState().getZone(cardInExile.getId()).equals(Zone.EXILED)) {
CardUtil.makeCardPlayableAndSpendManaAsAnyColor(game, source, cardInExile, Duration.Custom);
return true;
}
return false;
}
}