[40K] Implemented Shard of the Nightbringer

This commit is contained in:
Evan Kranzler 2022-10-11 20:56:31 -04:00
parent 9717d44963
commit 4d81b76180
4 changed files with 98 additions and 10 deletions

View file

@ -0,0 +1,87 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ShardOfTheNightbringer extends CardImpl {
public ShardOfTheNightbringer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}");
this.subtype.add(SubType.CTAN);
this.power = new MageInt(8);
this.toughness = new MageInt(8);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Drain Life -- When Shard of the Nightbringer enters the battlefield, if you cast it, target opponent loses half their life, rounded up. You gain life equal to the life lost this way.
Ability ability = new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new ShardOfTheNightbringerEffect()),
CastFromEverywhereSourceCondition.instance, "When {this} enters the battlefield, " +
"if you cast it, target opponent loses half their life, rounded up. " +
"You gain life equal to the life lost this way."
);
ability.addTarget(new TargetOpponent());
this.addAbility(ability.withFlavorWord("Drain Life"));
}
private ShardOfTheNightbringer(final ShardOfTheNightbringer card) {
super(card);
}
@Override
public ShardOfTheNightbringer copy() {
return new ShardOfTheNightbringer(this);
}
}
class ShardOfTheNightbringerEffect extends OneShotEffect {
ShardOfTheNightbringerEffect() {
super(Outcome.Benefit);
}
private ShardOfTheNightbringerEffect(final ShardOfTheNightbringerEffect effect) {
super(effect);
}
@Override
public ShardOfTheNightbringerEffect copy() {
return new ShardOfTheNightbringerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (opponent == null) {
return false;
}
int lifeLost = opponent.loseLife(
opponent.getLife() / 2 + opponent.getLife() % 2, game, source, false
);
if (lifeLost < 1) {
return false;
}
Player controller = game.getPlayer(source.getControllerId());
return controller == null || controller.gainLife(lifeLost, game, source) > 0;
}
}

View file

@ -200,6 +200,7 @@ public final class Warhammer40000 extends ExpansionSet {
cards.add(new SetCardInfo("Scoured Barrens", 293, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
cards.add(new SetCardInfo("Screamer-Killer", 84, Rarity.RARE, mage.cards.s.ScreamerKiller.class));
cards.add(new SetCardInfo("Sculpting Steel", 247, Rarity.RARE, mage.cards.s.SculptingSteel.class));
cards.add(new SetCardInfo("Shard of the Nightbringer", 55, Rarity.RARE, mage.cards.s.ShardOfTheNightbringer.class));
cards.add(new SetCardInfo("Sicarian Infiltrator", 25, Rarity.UNCOMMON, mage.cards.s.SicarianInfiltrator.class));
cards.add(new SetCardInfo("Sister Hospitaller", 141, Rarity.RARE, mage.cards.s.SisterHospitaller.class));
cards.add(new SetCardInfo("Sister Repentia", 142, Rarity.RARE, mage.cards.s.SisterRepentia.class));

View file

@ -1321,15 +1321,16 @@ public class VerifyCardDataTest {
return;
}
Collection<String> expected = ref.subtypes;
List<String> expected = new ArrayList<>(ref.subtypes);
// fix names (e.g. Urzas to Urza's)
if (expected != null && expected.contains("Urzas")) {
expected = new ArrayList<>(expected);
for (ListIterator<String> it = ((List<String>) expected).listIterator(); it.hasNext(); ) {
if (it.next().equals("Urzas")) {
for (ListIterator<String> it = expected.listIterator(); it.hasNext(); ) {
switch (it.next()) {
case "Urzas":
it.set("Urza's");
}
break;
case "Ctan":
it.set("C'tan");
}
}
@ -1339,11 +1340,9 @@ public class VerifyCardDataTest {
.stream()
.map(SubType::toString)
.collect(Collectors.toSet());
actual.removeIf(subtypesToIgnore::contains);
if (expected != null) {
expected.removeIf(subtypesToIgnore::contains);
}
actual.removeIf(subtypesToIgnore::contains);
expected.removeIf(subtypesToIgnore::contains);
for (SubType subType : card.getSubtype()) {
if (!subType.isCustomSet() && !subType.canGain(card)) {

View file

@ -116,6 +116,7 @@ public enum SubType {
CRAB("Crab", SubTypeSet.CreatureType),
CROCODILE("Crocodile", SubTypeSet.CreatureType),
CROLUTE("Crolute", SubTypeSet.CreatureType, true), // Star Wars
CTAN("C'tan", SubTypeSet.CreatureType),
CUSTODES("Custodes", SubTypeSet.CreatureType),
CYBORG("Cyborg", SubTypeSet.CreatureType, true), // Star Wars
CYCLOPS("Cyclops", SubTypeSet.CreatureType),