mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
[NEO] Implemented Kumano Faces Kakkazan / Etching of Kumano (#8674)
* [NEO] Implemented Kumano Faces Kakkazan / Etching of Kumano * [NEO] Etching of Kumano - Clean up watcher controller check Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
parent
cff38b74b9
commit
0694fd3ef7
4 changed files with 311 additions and 0 deletions
88
Mage.Sets/src/mage/cards/e/EtchingOfKumano.java
Normal file
88
Mage.Sets/src/mage/cards/e/EtchingOfKumano.java
Normal file
|
@ -0,0 +1,88 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.constants.*;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.watchers.common.DamagedByControlledWatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class EtchingOfKumano extends CardImpl {
|
||||
|
||||
public EtchingOfKumano(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.SHAMAN);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
this.color.setRed(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Haste
|
||||
this.addAbility(HasteAbility.getInstance());
|
||||
|
||||
// If a creature dealt damage this turn by a source you controlled would die, exile it instead.
|
||||
this.addAbility(new SimpleStaticAbility(new EtchingOfKumanoReplacementEffect()), new DamagedByControlledWatcher());
|
||||
}
|
||||
|
||||
private EtchingOfKumano(final EtchingOfKumano card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EtchingOfKumano copy() {
|
||||
return new EtchingOfKumano(this);
|
||||
}
|
||||
}
|
||||
|
||||
class EtchingOfKumanoReplacementEffect extends ReplacementEffectImpl {
|
||||
|
||||
public EtchingOfKumanoReplacementEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Exile);
|
||||
this.staticText = "If a creature dealt damage this turn by a source you controlled would die, exile it instead";
|
||||
}
|
||||
|
||||
private EtchingOfKumanoReplacementEffect(final EtchingOfKumanoReplacementEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EtchingOfKumanoReplacementEffect copy() {
|
||||
return new EtchingOfKumanoReplacementEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
ZoneChangeEvent zce = (ZoneChangeEvent) event;
|
||||
if (zce.isDiesEvent()) {
|
||||
DamagedByControlledWatcher watcher = game.getState().getWatcher(DamagedByControlledWatcher.class, source.getControllerId());
|
||||
if (watcher != null) {
|
||||
return watcher.wasDamaged(zce.getTarget(), game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
176
Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java
Normal file
176
Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java
Normal file
|
@ -0,0 +1,176 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.SagaAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.constants.*;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.EntersTheBattlefieldEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class KumanoFacesKakkazan extends CardImpl {
|
||||
|
||||
public KumanoFacesKakkazan(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}");
|
||||
|
||||
this.subtype.add(SubType.SAGA);
|
||||
this.secondSideCardClazz = mage.cards.e.EtchingOfKumano.class;
|
||||
|
||||
// (As this Saga enters and after your draw step, add a lore counter.)
|
||||
SagaAbility sagaAbility = new SagaAbility(this);
|
||||
|
||||
// I — Kumano Faces Kakkazan deals 1 damage to each opponent and each planeswalker they control.
|
||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new KumanoFacesKakkazanDamageEffect());
|
||||
|
||||
// II — When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it.
|
||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new CreateDelayedTriggeredAbilityEffect(new KumanoFacesKakkazanTriggeredAbility()));
|
||||
|
||||
// III — Exile this Saga, then return it to the battlefield transformed under your control.
|
||||
this.addAbility(new TransformAbility());
|
||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect());
|
||||
|
||||
this.addAbility(sagaAbility);
|
||||
}
|
||||
|
||||
private KumanoFacesKakkazan(final KumanoFacesKakkazan card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KumanoFacesKakkazan copy() {
|
||||
return new KumanoFacesKakkazan(this);
|
||||
}
|
||||
}
|
||||
|
||||
class KumanoFacesKakkazanDamageEffect extends OneShotEffect {
|
||||
|
||||
public KumanoFacesKakkazanDamageEffect() {
|
||||
super(Outcome.Damage);
|
||||
this.staticText = "{this} deals 1 damage to each opponent and each planeswalker they control";
|
||||
}
|
||||
|
||||
private KumanoFacesKakkazanDamageEffect(final KumanoFacesKakkazanDamageEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KumanoFacesKakkazanDamageEffect copy() {
|
||||
return new KumanoFacesKakkazanDamageEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Set<UUID> opponents = game.getOpponents(source.getControllerId());
|
||||
if (opponents.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (UUID opponentId : opponents) {
|
||||
Player opponent = game.getPlayer(opponentId);
|
||||
if (opponent != null) {
|
||||
opponent.damage(1, source, game);
|
||||
}
|
||||
}
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(CardType.PLANESWALKER, game)) {
|
||||
if (opponents.contains(permanent.getControllerId())) {
|
||||
permanent.damage(1, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class KumanoFacesKakkazanTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
public KumanoFacesKakkazanTriggeredAbility() {
|
||||
super(null, Duration.EndOfTurn);
|
||||
}
|
||||
|
||||
private KumanoFacesKakkazanTriggeredAbility(final KumanoFacesKakkazanTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KumanoFacesKakkazanTriggeredAbility copy() {
|
||||
return new KumanoFacesKakkazanTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.SPELL_CAST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (this.isControlledBy(event.getPlayerId())) {
|
||||
Spell spell = game.getSpell(event.getTargetId());
|
||||
if (spell != null && spell.isCreature(game)) {
|
||||
this.getEffects().clear();
|
||||
this.getEffects().add(new KumanoFacesKakkazanCounterEffect(spell.getSourceId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it.";
|
||||
}
|
||||
}
|
||||
|
||||
class KumanoFacesKakkazanCounterEffect extends ReplacementEffectImpl {
|
||||
|
||||
private final UUID spellCastId;
|
||||
|
||||
public KumanoFacesKakkazanCounterEffect(UUID spellCastId) {
|
||||
super(Duration.EndOfTurn, Outcome.BoostCreature);
|
||||
this.spellCastId = spellCastId;
|
||||
}
|
||||
|
||||
private KumanoFacesKakkazanCounterEffect(final KumanoFacesKakkazanCounterEffect effect) {
|
||||
super(effect);
|
||||
this.spellCastId = effect.spellCastId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KumanoFacesKakkazanCounterEffect copy() {
|
||||
return new KumanoFacesKakkazanCounterEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
return spellCastId.equals(event.getTargetId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
if (creature != null) {
|
||||
creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -89,6 +89,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Enthusiastic Mechanaut", 218, Rarity.UNCOMMON, mage.cards.e.EnthusiasticMechanaut.class));
|
||||
cards.add(new SetCardInfo("Era of Enlightenment", 11, Rarity.COMMON, mage.cards.e.EraOfEnlightenment.class));
|
||||
cards.add(new SetCardInfo("Essence Capture", 52, Rarity.UNCOMMON, mage.cards.e.EssenceCapture.class));
|
||||
cards.add(new SetCardInfo("Etching of Kumano", 152, Rarity.UNCOMMON, mage.cards.e.EtchingOfKumano.class));
|
||||
cards.add(new SetCardInfo("Experimental Synthesizer", 138, Rarity.COMMON, mage.cards.e.ExperimentalSynthesizer.class));
|
||||
cards.add(new SetCardInfo("Explosive Entry", 139, Rarity.COMMON, mage.cards.e.ExplosiveEntry.class));
|
||||
cards.add(new SetCardInfo("Explosive Singularity", 140, Rarity.MYTHIC, mage.cards.e.ExplosiveSingularity.class));
|
||||
|
@ -165,6 +166,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Kitsune Ace", 22, Rarity.COMMON, mage.cards.k.KitsuneAce.class));
|
||||
cards.add(new SetCardInfo("Kodama of the West Tree", 199, Rarity.MYTHIC, mage.cards.k.KodamaOfTheWestTree.class));
|
||||
cards.add(new SetCardInfo("Kotose, the Silent Spider", 351, Rarity.RARE, mage.cards.k.KotoseTheSilentSpider.class));
|
||||
cards.add(new SetCardInfo("Kumano Faces Kakkazan", 152, Rarity.UNCOMMON, mage.cards.k.KumanoFacesKakkazan.class));
|
||||
cards.add(new SetCardInfo("Kura, the Boundless Sky", 200, Rarity.MYTHIC, mage.cards.k.KuraTheBoundlessSky.class));
|
||||
cards.add(new SetCardInfo("Kyodai, Soul of Kamigawa", 23, Rarity.RARE, mage.cards.k.KyodaiSoulOfKamigawa.class));
|
||||
cards.add(new SetCardInfo("Leech Gauntlet", 106, Rarity.UNCOMMON, mage.cards.l.LeechGauntlet.class));
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package mage.watchers.common;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public class DamagedByControlledWatcher extends Watcher {
|
||||
|
||||
private final HashSet<MageObjectReference> damagedPermanents = new HashSet<>();
|
||||
|
||||
public DamagedByControlledWatcher() {
|
||||
super(WatcherScope.PLAYER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null && permanent.isCreature(game)) {
|
||||
if (controllerId != null && controllerId.equals(game.getControllerId(event.getSourceId()))) {
|
||||
damagedPermanents.add(new MageObjectReference(event.getTargetId(), game));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
damagedPermanents.clear();
|
||||
}
|
||||
|
||||
public boolean wasDamaged(Permanent permanent, Game game) {
|
||||
return damagedPermanents.contains(new MageObjectReference(permanent, game));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue