Skip to content

Commit

Permalink
[DSK] Implement Kaito, Bane of Nightmares (#13187)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackd149 authored Jan 3, 2025
1 parent 48117b9 commit fd4b826
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,9 @@ public class ScryfallImageSupportTokens {
// BLC
put("BLC/Raccoon", "https://api.scryfall.com/cards/tblc/29/en?format=image");

// DSK
put("DSK/Emblem Kaito", "https://api.scryfall.com/cards/tdsk/17/en?format=image");

// FDN
put("FDN/Beast/1", "https://api.scryfall.com/cards/tfdn/32/en?format=image");
put("FDN/Beast/2", "https://api.scryfall.com/cards/tfdn/33/en?format=image");
Expand Down
132 changes: 132 additions & 0 deletions Mage.Sets/src/mage/cards/k/KaitoBaneOfNightmares.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package mage.cards.k;

import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.HexproofAbility;
import mage.abilities.keyword.NinjutsuAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.command.emblems.KaitoBaneOfNightmaresEmblem;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.custom.CreatureToken;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.PlayerLostLifeWatcher;

import java.util.UUID;

/**
*
* @author jackd149
*/
public final class KaitoBaneOfNightmares extends CardImpl {

public KaitoBaneOfNightmares(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{B}");

this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.KAITO);
this.setStartingLoyalty(4);

// Ninjutsu {1}{U}{B}
this.addAbility(new NinjutsuAbility("{1}{U}{B}"));

// During your turn, as long as Kaito has one or more loyalty counters on him, he's a 3/4 Ninja creature and has hexproof.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new BecomesCreatureSourceEffect(
new CreatureToken(3, 4, "3/4 Ninja creature")
.withSubType(SubType.NINJA)
.withAbility(HexproofAbility.getInstance()), null, Duration.WhileOnBattlefield
), KaitoBaneOfNightmaresCondition.instance, "During your turn, as long as {this} has one or more loyalty counters on him, " +
"he's a 3/4 Ninja creature and has hexproof."
)).addHint(MyTurnHint.instance));

// +1: You get an emblem with "Ninjas you control get +1/+1."
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KaitoBaneOfNightmaresEmblem()), 1));

// 0: Surveil 2. Then draw a card for each opponent who lost life this turn.
Ability ability = new LoyaltyAbility(new SurveilEffect(2), 0);
ability.addEffect(new DrawCardSourceControllerEffect(KaitoBaneOfNightmaresCount.instance));
this.addAbility(ability, new PlayerLostLifeWatcher());

// -2: Tap target creature. Put two stun counters on it.
Ability minusTwoAbility = new LoyaltyAbility(new TapTargetEffect(), -2);
minusTwoAbility.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance(2))
.setText("Put two stun counters on it"));
minusTwoAbility.addTarget(new TargetCreaturePermanent());
this.addAbility(minusTwoAbility);
}

private KaitoBaneOfNightmares(final KaitoBaneOfNightmares card) {
super(card);
}

@Override
public KaitoBaneOfNightmares copy() {
return new KaitoBaneOfNightmares(this);
}
}

enum KaitoBaneOfNightmaresCondition implements Condition {
instance;

@Override
public boolean apply(Game game, Ability source) {
if (!MyTurnCondition.instance.apply(game, source)){
return false;
}

Permanent permanent = game.getPermanent(source.getSourceId());

if (permanent == null) {
return false;
}

int loyaltyCount = permanent.getCounters(game).getCount(CounterType.LOYALTY);
return loyaltyCount > 0;

}
}

enum KaitoBaneOfNightmaresCount implements DynamicValue {
instance;

@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
PlayerLostLifeWatcher watcher = game.getState().getWatcher(PlayerLostLifeWatcher.class);
if (watcher != null) {
return watcher.getNumberOfOpponentsWhoLostLife(sourceAbility.getControllerId(), game);
}
return 0;
}

@Override
public KaitoBaneOfNightmaresCount copy() {
return instance;
}

@Override
public String toString() {
return "1";
}

@Override
public String getMessage() {
return "opponent who lost life this turn.";
}
}
4 changes: 4 additions & 0 deletions Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ private DuskmournHouseOfHorror() {
cards.add(new SetCardInfo("Irreverent Gremlin", 142, Rarity.UNCOMMON, mage.cards.i.IrreverentGremlin.class));
cards.add(new SetCardInfo("Island", 273, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Jump Scare", 17, Rarity.COMMON, mage.cards.j.JumpScare.class));
cards.add(new SetCardInfo("Kaito, Bane of Nightmares", 220, Rarity.MYTHIC, mage.cards.k.KaitoBaneOfNightmares.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kaito, Bane of Nightmares", 328, Rarity.MYTHIC, mage.cards.k.KaitoBaneOfNightmares.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kaito, Bane of Nightmares", 354, Rarity.MYTHIC, mage.cards.k.KaitoBaneOfNightmares.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kaito, Bane of Nightmares", 409, Rarity.MYTHIC, mage.cards.k.KaitoBaneOfNightmares.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Killer's Mask", 104, Rarity.UNCOMMON, mage.cards.k.KillersMask.class));
cards.add(new SetCardInfo("Kona, Rescue Beastie", 187, Rarity.RARE, mage.cards.k.KonaRescueBeastie.class));
cards.add(new SetCardInfo("Lakeside Shack", 262, Rarity.COMMON, mage.cards.l.LakesideShack.class));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package mage.game.command.emblems;

import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.command.Emblem;

/**
* @author jackd149
*/
public final class KaitoBaneOfNightmaresEmblem extends Emblem {

public KaitoBaneOfNightmaresEmblem() {
super("Emblem Kaito");
FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.NINJA, "Ninjas you control");
this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new BoostControlledEffect(1, 1, Duration.EndOfGame, filter, false)));
}

private KaitoBaneOfNightmaresEmblem(final KaitoBaneOfNightmaresEmblem card) {
super(card);
}

@Override
public KaitoBaneOfNightmaresEmblem copy() {
return new KaitoBaneOfNightmaresEmblem(this);
}

}
13 changes: 13 additions & 0 deletions Mage/src/main/java/mage/watchers/common/PlayerLostLifeWatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ public int getAllOppLifeLost(UUID playerId, Game game) {
return amount;
}

public int getNumberOfOpponentsWhoLostLife(UUID playerId, Game game) {
int numPlayersLostLife = 0;
for (UUID opponentId : this.amountOfLifeLostThisTurn.keySet()) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null && opponent.hasOpponent(playerId, game)) {
if (this.amountOfLifeLostThisTurn.getOrDefault(opponentId, 0) > 0) {
numPlayersLostLife++;
}
}
}
return numPlayersLostLife;
}

public int getLifeLostLastTurn(UUID playerId) {
return amountOfLifeLostLastTurn.getOrDefault(playerId, 0);
}
Expand Down
1 change: 1 addition & 0 deletions Mage/src/main/resources/tokens-database.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
|Generate|EMBLEM:M3C|Emblem Vivien|||VivienReidEmblem|
|Generate|EMBLEM:ACR|Emblem Capitoline Triad|||TheCapitolineTriadEmblem|
|Generate|EMBLEM:BLB|Emblem Ral|||RalCracklingWitEmblem|
|Generate|EMBLEM:DSK|Emblem Kaito|||KaitoBaneOfNightmaresEmblem|
|Generate|EMBLEM:FDN|Emblem Kaito|||KaitoCunningInfiltratorEmblem|
|Generate|EMBLEM:FDN|Emblem Vivien|||VivienReidEmblem|

Expand Down

0 comments on commit fd4b826

Please sign in to comment.