Skip to content

Commit 7b7c80c

Browse files
committed
[WAR] added God-Eternal Kefnet
1 parent a737df0 commit 7b7c80c

File tree

3 files changed

+178
-9
lines changed

3 files changed

+178
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package mage.cards.g;
2+
3+
import mage.MageInt;
4+
import mage.MageObjectReference;
5+
import mage.abilities.Ability;
6+
import mage.abilities.common.GodEternalDiesTriggeredAbility;
7+
import mage.abilities.common.SimpleStaticAbility;
8+
import mage.abilities.effects.ReplacementEffectImpl;
9+
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
10+
import mage.abilities.hint.HintUtils;
11+
import mage.abilities.keyword.FlyingAbility;
12+
import mage.cards.Card;
13+
import mage.cards.CardImpl;
14+
import mage.cards.CardSetInfo;
15+
import mage.constants.*;
16+
import mage.game.Game;
17+
import mage.game.events.GameEvent;
18+
import mage.game.events.GameEvent.EventType;
19+
import mage.game.permanent.Permanent;
20+
import mage.players.Player;
21+
import mage.watchers.common.CardsAmountDrawnThisTurnWatcher;
22+
23+
import java.awt.*;
24+
import java.util.UUID;
25+
26+
/**
27+
* @author JayDi85
28+
*/
29+
public final class GodEternalKefnet extends CardImpl {
30+
31+
public GodEternalKefnet(UUID ownerId, CardSetInfo setInfo) {
32+
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
33+
this.addSuperType(SuperType.LEGENDARY);
34+
this.subtype.add(SubType.ZOMBIE);
35+
this.subtype.add(SubType.GOD);
36+
37+
this.power = new MageInt(4);
38+
this.toughness = new MageInt(5);
39+
40+
// Flying
41+
this.addAbility(FlyingAbility.getInstance());
42+
43+
// You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant or sorcery card this way,
44+
// copy that card and you may cast the copy. That copy costs {2} less to cast.
45+
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GodEternalKefnetDrawCardReplacementEffect()), new CardsAmountDrawnThisTurnWatcher());
46+
47+
// 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.
48+
this.addAbility(new GodEternalDiesTriggeredAbility());
49+
}
50+
51+
public GodEternalKefnet(final GodEternalKefnet card) {
52+
super(card);
53+
}
54+
55+
@Override
56+
public GodEternalKefnet copy() {
57+
return new GodEternalKefnet(this);
58+
}
59+
}
60+
61+
class GodEternalKefnetDrawCardReplacementEffect extends ReplacementEffectImpl {
62+
63+
public GodEternalKefnetDrawCardReplacementEffect() {
64+
super(Duration.WhileOnBattlefield, Outcome.Neutral);
65+
this.staticText = "You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant "
66+
+ "or sorcery card this way, copy that card and you may cast the copy. That copy costs {2} less to cast";
67+
}
68+
69+
public GodEternalKefnetDrawCardReplacementEffect(final GodEternalKefnetDrawCardReplacementEffect effect) {
70+
super(effect);
71+
}
72+
73+
@Override
74+
public GodEternalKefnetDrawCardReplacementEffect copy() {
75+
return new GodEternalKefnetDrawCardReplacementEffect(this);
76+
}
77+
78+
@Override
79+
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
80+
// reveal top card and drawn (return false to continue default draw)
81+
Permanent god = game.getPermanent(source.getSourceId());
82+
Player you = game.getPlayer(source.getControllerId());
83+
if (god == null && you == null) {
84+
return false;
85+
}
86+
87+
Card topCard = you.getLibrary().getTopCards(game, 1).iterator().next();
88+
if (topCard == null) {
89+
return false;
90+
}
91+
92+
// reveal
93+
you.setTopCardRevealed(true);
94+
95+
// cast copy
96+
if (topCard.isInstantOrSorcery() && you.chooseUse(outcome, "Would you like to copy " + topCard.getName()
97+
+ " and cast it {2} less?", source, game)) {
98+
Card blueprint = topCard.copy();
99+
blueprint.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(2)));
100+
Card copiedCard = game.copyCard(blueprint, source, source.getControllerId());
101+
you.moveCardToHandWithInfo(copiedCard, source.getSourceId(), game, true); // The copy is created in and cast from your hand.
102+
you.cast(copiedCard.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
103+
}
104+
105+
// draw (return false for default draw)
106+
return false;
107+
}
108+
109+
@Override
110+
public boolean checksEventType(GameEvent event, Game game) {
111+
return event.getType() == EventType.DRAW_CARD;
112+
}
113+
114+
String getAppliedMark(Game game, Ability source) {
115+
return source.getId() + "-applied-" + source.getControllerId() + "-" + game.getState().getTurnNum();
116+
}
117+
118+
@Override
119+
public boolean applies(GameEvent event, Ability source, Game game) {
120+
if (!event.getPlayerId().equals(source.getControllerId())) {
121+
return false;
122+
}
123+
124+
Permanent god = game.getPermanent(source.getSourceId());
125+
Player you = game.getPlayer(source.getControllerId());
126+
if (god == null && you == null) {
127+
return false;
128+
}
129+
130+
Card topCard = you.getLibrary().getTopCards(game, 1).iterator().next();
131+
if (topCard == null) {
132+
return false;
133+
}
134+
135+
// only first draw card
136+
// if card casted on that turn or controlled changed then needs history from watcher
137+
CardsAmountDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class);
138+
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 0) {
139+
return false;
140+
}
141+
142+
// one time use (if multiple cards drawn)
143+
String mark = getAppliedMark(game, source);
144+
if (game.getState().getValue(mark) != null) {
145+
return false;
146+
}
147+
game.getState().setValue(mark, true);
148+
149+
// ask player to reveal top cards
150+
String mes = topCard.getName() + ", " + (topCard.isInstantOrSorcery()
151+
? HintUtils.prepareText("you can copy it and cast {2} less", Color.green)
152+
: HintUtils.prepareText("you can't copy it", Color.red));
153+
return you.chooseUse(Outcome.Benefit, "Would you like to reveal first drawn card (" + mes + ")?", source, game);
154+
}
155+
156+
}
157+

Mage.Sets/src/mage/sets/WarOfTheSpark.java

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ private WarOfTheSpark() {
125125
cards.add(new SetCardInfo("Goblin Assailant", 128, Rarity.COMMON, mage.cards.g.GoblinAssailant.class));
126126
cards.add(new SetCardInfo("Goblin Assault Team", 129, Rarity.COMMON, mage.cards.g.GoblinAssaultTeam.class));
127127
cards.add(new SetCardInfo("God-Eternal Bontu", 92, Rarity.MYTHIC, mage.cards.g.GodEternalBontu.class));
128+
cards.add(new SetCardInfo("God-Eternal Kefnet", 53, Rarity.MYTHIC, mage.cards.g.GodEternalKefnet.class));
128129
cards.add(new SetCardInfo("God-Eternal Oketra", 16, Rarity.MYTHIC, mage.cards.g.GodEternalOketra.class));
129130
cards.add(new SetCardInfo("God-Eternal Rhonas", 163, Rarity.MYTHIC, mage.cards.g.GodEternalRhonas.class));
130131
cards.add(new SetCardInfo("God-Pharaoh's Statue", 238, Rarity.UNCOMMON, mage.cards.g.GodPharaohsStatue.class));

Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java

+20-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
package mage.abilities.effects.common.cost;
32

43
import mage.abilities.Ability;
@@ -13,14 +12,17 @@
1312
import mage.util.CardUtil;
1413

1514
/**
16-
*
1715
* @author LevelX2
1816
*/
1917
public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
2018

2119
private final int amount;
2220
private ManaCosts<ManaCost> manaCostsToReduce = null;
23-
private final Condition condition;
21+
private Condition condition;
22+
23+
public SpellCostReductionSourceEffect(ManaCosts<ManaCost> manaCostsToReduce) {
24+
this(manaCostsToReduce, null);
25+
}
2426

2527
public SpellCostReductionSourceEffect(ManaCosts<ManaCost> manaCostsToReduce, Condition condition) {
2628
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
@@ -33,19 +35,28 @@ public SpellCostReductionSourceEffect(ManaCosts<ManaCost> manaCostsToReduce, Con
3335
for (String manaSymbol : manaCostsToReduce.getSymbols()) {
3436
sb.append(manaSymbol);
3537
}
36-
sb.append(" less to if ").append(this.condition.toString());
38+
sb.append(" less");
39+
if (this.condition != null) {
40+
sb.append(" to if ").append(this.condition.toString());
41+
}
42+
3743
this.staticText = sb.toString();
3844
}
3945

46+
public SpellCostReductionSourceEffect(int amount) {
47+
this(amount, null);
48+
}
49+
4050
public SpellCostReductionSourceEffect(int amount, Condition condition) {
4151
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
4252
this.amount = amount;
4353
this.condition = condition;
4454
StringBuilder sb = new StringBuilder();
45-
sb.append("{this} costs {")
46-
.append(amount).append("} less to cast ")
47-
.append((this.condition.toString().startsWith("if ") ? "" : "if "))
48-
.append(this.condition.toString());
55+
sb.append("{this} costs {").append(amount).append("} less to cast");
56+
if (this.condition != null) {
57+
sb.append(" ").append(this.condition.toString().startsWith("if ") ? "" : "if ");
58+
sb.append(this.condition.toString());
59+
}
4960
this.staticText = sb.toString();
5061
}
5162

@@ -69,7 +80,7 @@ public boolean apply(Game game, Ability source, Ability abilityToModify) {
6980
@Override
7081
public boolean applies(Ability abilityToModify, Ability source, Game game) {
7182
if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) {
72-
return condition.apply(game, source);
83+
return condition == null || condition.apply(game, source);
7384
}
7485
return false;
7586
}

0 commit comments

Comments
 (0)