diff --git a/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java b/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java new file mode 100644 index 000000000000..8e1ce4c277f2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GodEternalKefnet.java @@ -0,0 +1,157 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.GodEternalDiesTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.abilities.hint.HintUtils; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.common.CardsAmountDrawnThisTurnWatcher; + +import java.awt.*; +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class GodEternalKefnet extends CardImpl { + + public GodEternalKefnet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.GOD); + + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant or sorcery card this way, + // copy that card and you may cast the copy. That copy costs {2} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GodEternalKefnetDrawCardReplacementEffect()), new CardsAmountDrawnThisTurnWatcher()); + + // When God-Eternal Kefnet dies or is put into exile from the battlefield, you may put it into its owner’s library third from the top. + this.addAbility(new GodEternalDiesTriggeredAbility()); + } + + public GodEternalKefnet(final GodEternalKefnet card) { + super(card); + } + + @Override + public GodEternalKefnet copy() { + return new GodEternalKefnet(this); + } +} + +class GodEternalKefnetDrawCardReplacementEffect extends ReplacementEffectImpl { + + public GodEternalKefnetDrawCardReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + this.staticText = "You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant " + + "or sorcery card this way, copy that card and you may cast the copy. That copy costs {2} less to cast"; + } + + public GodEternalKefnetDrawCardReplacementEffect(final GodEternalKefnetDrawCardReplacementEffect effect) { + super(effect); + } + + @Override + public GodEternalKefnetDrawCardReplacementEffect copy() { + return new GodEternalKefnetDrawCardReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + // reveal top card and drawn (return false to continue default draw) + Permanent god = game.getPermanent(source.getSourceId()); + Player you = game.getPlayer(source.getControllerId()); + if (god == null && you == null) { + return false; + } + + Card topCard = you.getLibrary().getTopCards(game, 1).iterator().next(); + if (topCard == null) { + return false; + } + + // reveal + you.setTopCardRevealed(true); + + // cast copy + if (topCard.isInstantOrSorcery() && you.chooseUse(outcome, "Would you like to copy " + topCard.getName() + + " and cast it {2} less?", source, game)) { + Card blueprint = topCard.copy(); + blueprint.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(2))); + Card copiedCard = game.copyCard(blueprint, source, source.getControllerId()); + you.moveCardToHandWithInfo(copiedCard, source.getSourceId(), game, true); // The copy is created in and cast from your hand. + you.cast(copiedCard.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game)); + } + + // draw (return false for default draw) + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.DRAW_CARD; + } + + String getAppliedMark(Game game, Ability source) { + return source.getId() + "-applied-" + source.getControllerId() + "-" + game.getState().getTurnNum(); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!event.getPlayerId().equals(source.getControllerId())) { + return false; + } + + Permanent god = game.getPermanent(source.getSourceId()); + Player you = game.getPlayer(source.getControllerId()); + if (god == null && you == null) { + return false; + } + + Card topCard = you.getLibrary().getTopCards(game, 1).iterator().next(); + if (topCard == null) { + return false; + } + + // only first draw card + // if card casted on that turn or controlled changed then needs history from watcher + CardsAmountDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class); + if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 0) { + return false; + } + + // one time use (if multiple cards drawn) + String mark = getAppliedMark(game, source); + if (game.getState().getValue(mark) != null) { + return false; + } + game.getState().setValue(mark, true); + + // ask player to reveal top cards + String mes = topCard.getName() + ", " + (topCard.isInstantOrSorcery() + ? HintUtils.prepareText("you can copy it and cast {2} less", Color.green) + : HintUtils.prepareText("you can't copy it", Color.red)); + return you.chooseUse(Outcome.Benefit, "Would you like to reveal first drawn card (" + mes + ")?", source, game); + } + +} + diff --git a/Mage.Sets/src/mage/sets/WarOfTheSpark.java b/Mage.Sets/src/mage/sets/WarOfTheSpark.java index eb42558d8ec4..c4ec025a005f 100644 --- a/Mage.Sets/src/mage/sets/WarOfTheSpark.java +++ b/Mage.Sets/src/mage/sets/WarOfTheSpark.java @@ -125,6 +125,7 @@ private WarOfTheSpark() { cards.add(new SetCardInfo("Goblin Assailant", 128, Rarity.COMMON, mage.cards.g.GoblinAssailant.class)); cards.add(new SetCardInfo("Goblin Assault Team", 129, Rarity.COMMON, mage.cards.g.GoblinAssaultTeam.class)); cards.add(new SetCardInfo("God-Eternal Bontu", 92, Rarity.MYTHIC, mage.cards.g.GodEternalBontu.class)); + cards.add(new SetCardInfo("God-Eternal Kefnet", 53, Rarity.MYTHIC, mage.cards.g.GodEternalKefnet.class)); cards.add(new SetCardInfo("God-Eternal Oketra", 16, Rarity.MYTHIC, mage.cards.g.GodEternalOketra.class)); cards.add(new SetCardInfo("God-Eternal Rhonas", 163, Rarity.MYTHIC, mage.cards.g.GodEternalRhonas.class)); cards.add(new SetCardInfo("God-Pharaoh's Statue", 238, Rarity.UNCOMMON, mage.cards.g.GodPharaohsStatue.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java index 32a056f59938..4e62811543fd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common.cost; import mage.abilities.Ability; @@ -13,14 +12,17 @@ import mage.util.CardUtil; /** - * * @author LevelX2 */ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { private final int amount; private ManaCosts manaCostsToReduce = null; - private final Condition condition; + private Condition condition; + + public SpellCostReductionSourceEffect(ManaCosts manaCostsToReduce) { + this(manaCostsToReduce, null); + } public SpellCostReductionSourceEffect(ManaCosts manaCostsToReduce, Condition condition) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); @@ -33,19 +35,28 @@ public SpellCostReductionSourceEffect(ManaCosts manaCostsToReduce, Con for (String manaSymbol : manaCostsToReduce.getSymbols()) { sb.append(manaSymbol); } - sb.append(" less to if ").append(this.condition.toString()); + sb.append(" less"); + if (this.condition != null) { + sb.append(" to if ").append(this.condition.toString()); + } + this.staticText = sb.toString(); } + public SpellCostReductionSourceEffect(int amount) { + this(amount, null); + } + public SpellCostReductionSourceEffect(int amount, Condition condition) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.amount = amount; this.condition = condition; StringBuilder sb = new StringBuilder(); - sb.append("{this} costs {") - .append(amount).append("} less to cast ") - .append((this.condition.toString().startsWith("if ") ? "" : "if ")) - .append(this.condition.toString()); + sb.append("{this} costs {").append(amount).append("} less to cast"); + if (this.condition != null) { + sb.append(" ").append(this.condition.toString().startsWith("if ") ? "" : "if "); + sb.append(this.condition.toString()); + } this.staticText = sb.toString(); } @@ -69,7 +80,7 @@ public boolean apply(Game game, Ability source, Ability abilityToModify) { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) { - return condition.apply(game, source); + return condition == null || condition.apply(game, source); } return false; }