Merge branch 'master' into tyvar-kell

This commit is contained in:
Oleg Agafonov 2021-01-12 01:45:58 +01:00 committed by GitHub
commit b184fa7842
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1183 additions and 45 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.b;
import java.util.UUID;
@ -44,7 +43,7 @@ public final class Blightning extends CardImpl {
class BlightningEffect extends OneShotEffect {
BlightningEffect() {
super(Outcome.Benefit);
super(Outcome.Detriment);
this.staticText = "That player or that planeswalker's controller discards two cards.";
}

View file

@ -0,0 +1,63 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BloodlinePretender extends CardImpl {
private static final FilterPermanent filter
= new FilterCreaturePermanent("another creature of the chosen type");
static {
filter.add(AnotherPredicate.instance);
filter.add(ChosenSubtypePredicate.instance);
}
public BloodlinePretender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// As Bloodline Pretender enters the battlefield, choose a creature type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature)));
// Whenever another creature of the chosen type enters the battlefield under your control, put a +1/+1 counter on Bloodline Pretender.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter
));
}
private BloodlinePretender(final BloodlinePretender card) {
super(card);
}
@Override
public BloodlinePretender copy() {
return new BloodlinePretender(this);
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.CantBeCounteredAbility;
import mage.abilities.common.CantBeCounteredSourceAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.KickedCondition;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@ -32,7 +32,7 @@ public final class CragplateBaloth extends CardImpl {
this.addAbility(new KickerAbility("{2}{G}"));
// This spell can't be countered.
this.addAbility(new CantBeCounteredAbility());
this.addAbility(new CantBeCounteredSourceAbility());
// Hexproof
this.addAbility(HexproofAbility.getInstance());

View file

@ -0,0 +1,64 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.SacrificeOpponentsEffect;
import mage.abilities.keyword.BoastAbility;
import mage.abilities.keyword.HexproofFromPlaneswalkersAbility;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author weirddan455
*/
public final class EradicatorValkyrie extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("creature or planeswalker");
static {
filter.add(Predicates.or(CardType.CREATURE.getPredicate(), CardType.PLANESWALKER.getPredicate()));
}
public EradicatorValkyrie(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.subtype.add(SubType.ANGEL);
this.subtype.add(SubType.BERSERKER);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// Hexproof from planeswalkers
this.addAbility(HexproofFromPlaneswalkersAbility.getInstance());
// Boast {1}{B}, Sacrifice a creature: Each opponent sacrifices a creature or planeswalker.
Ability ability = new BoastAbility(new SacrificeOpponentsEffect(filter), new ManaCostsImpl("{1}{B}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
this.addAbility(ability);
}
private EradicatorValkyrie(final EradicatorValkyrie card) {
super(card);
}
@Override
public EradicatorValkyrie copy() {
return new EradicatorValkyrie(this);
}
}

View file

@ -0,0 +1,65 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SuperType;
import mage.game.permanent.token.TokenImpl;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FacelessHaven extends CardImpl {
public FacelessHaven(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.addSuperType(SuperType.SNOW);
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());
// {S}{S}{S}: Faceless Haven becomes a 4/3 creature with vigilance and all creature types until end of turn. It's still a land.
this.addAbility(new SimpleActivatedAbility(new BecomesCreatureSourceEffect(
new FacelessHavenToken(), "land", Duration.EndOfTurn
), new ManaCostsImpl("{S}{S}{S}")));
}
private FacelessHaven(final FacelessHaven card) {
super(card);
}
@Override
public FacelessHaven copy() {
return new FacelessHaven(this);
}
}
class FacelessHavenToken extends TokenImpl {
FacelessHavenToken() {
super("", "4/3 creature with vigilance and all creature types");
cardType.add(CardType.CREATURE);
setIsAllCreatureTypes(true);
power = new MageInt(4);
toughness = new MageInt(3);
addAbility(VigilanceAbility.getInstance());
}
private FacelessHavenToken(final FacelessHavenToken token) {
super(token);
}
public FacelessHavenToken copy() {
return new FacelessHavenToken(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GuardianGladewalker extends CardImpl {
public GuardianGladewalker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Changeling
this.isAllCreatureTypes();
this.addAbility(ChangelingAbility.getInstance());
// When Guardian Gladewalker enters the battlefield, put a +1/+1 counter on target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance())
);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private GuardianGladewalker(final GuardianGladewalker card) {
super(card);
}
@Override
public GuardianGladewalker copy() {
return new GuardianGladewalker(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.BoastAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HagiMob extends CardImpl {
public HagiMob(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.subtype.add(SubType.TROLL);
this.subtype.add(SubType.BERSERKER);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
// Boast {1}{R}: Hagi Mob deals 1 damage to any target.
Ability ability = new BoastAbility(new DamageTargetEffect(1), new ManaCostsImpl("{1}{R}"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private HagiMob(final HagiMob card) {
super(card);
}
@Override
public HagiMob copy() {
return new HagiMob(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.k;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.ForetellAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KayasOnslaught extends CardImpl {
public KayasOnslaught(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
// Target creature gets +1/+1 and gains double strike until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(
1, 1, Duration.EndOfTurn
).setText("target creature gets +1/+1"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
DoubleStrikeAbility.getInstance(), Duration.EndOfTurn
).setText("and gains double strike until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Foretell {W}
this.addAbility(new ForetellAbility(this, "{W}"));
}
private KayasOnslaught(final KayasOnslaught card) {
super(card);
}
@Override
public KayasOnslaught copy() {
return new KayasOnslaught(this);
}
}

View file

@ -0,0 +1,88 @@
package mage.cards.l;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.*;
/**
* @author TheElk801
*/
public final class LittjaraKinseekers extends CardImpl {
public LittjaraKinseekers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// When Littjara Kinseekers enters the battlefield, if you control three or more creatures that share a creature type, put a +1/+1 counter on Littjara Kinseekers, then scry 1.
Ability ability = new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
), LittjaraKinseekersCondition.instance, "When {this} enters the battlefield, " +
"if you control three or more creatures that share a creature type, " +
"put a +1/+1 counter on {this}, then scry 1."
);
ability.addEffect(new ScryEffect(1));
this.addAbility(ability);
}
private LittjaraKinseekers(final LittjaraKinseekers card) {
super(card);
}
@Override
public LittjaraKinseekers copy() {
return new LittjaraKinseekers(this);
}
}
enum LittjaraKinseekersCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> permanentList = game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
source.getControllerId(), source.getSourceId(), game
);
permanentList.removeIf(Objects::isNull);
long changelings = permanentList
.stream()
.filter(Objects::nonNull)
.filter(MageObject::isAllCreatureTypes)
.count();
if (changelings > 2) {
return true;
}
permanentList.removeIf(MageObject::isAllCreatureTypes);
Map<SubType, Integer> typeMap = new HashMap<>();
return permanentList
.stream()
.map(permanent -> permanent.getSubtype(game))
.flatMap(Collection::stream)
.mapToInt(subType -> typeMap.compute(subType, (s, i) -> i == null ? 1 : Integer.sum(i, 1)))
.anyMatch(x -> x + changelings > 2);
}
}

View file

@ -0,0 +1,147 @@
package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.command.CommandObject;
import mage.game.command.Commander;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.ShapeshifterBlueToken;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MaskwoodNexus extends CardImpl {
public MaskwoodNexus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Creatures you control are every creature type. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.
this.addAbility(new SimpleStaticAbility(new MaskwoodNexusEffect()));
// {3}, {T}: Create a 2/2 blue Shapeshifter creature token with changeling.
Ability ability = new SimpleActivatedAbility(
new CreateTokenEffect(new ShapeshifterBlueToken()), new GenericManaCost(3)
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private MaskwoodNexus(final MaskwoodNexus card) {
super(card);
}
@Override
public MaskwoodNexus copy() {
return new MaskwoodNexus(this);
}
}
class MaskwoodNexusEffect extends ContinuousEffectImpl {
MaskwoodNexusEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "Creatures you control are every creature type. " +
"The same is true for creature spells you control " +
"and creature cards you own that aren't on the battlefield.";
}
private MaskwoodNexusEffect(final MaskwoodNexusEffect effect) {
super(effect);
}
@Override
public MaskwoodNexusEffect copy() {
return new MaskwoodNexusEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
// Creature cards you own that aren't on the battlefield
// in graveyard
for (UUID cardId : controller.getGraveyard()) {
Card card = game.getCard(cardId);
if (card != null && card.isCreature()) {
card.setIsAllCreatureTypes(true);
}
}
// on Hand
for (UUID cardId : controller.getHand()) {
Card card = game.getCard(cardId);
if (card != null && card.isCreature()) {
card.setIsAllCreatureTypes(true);
}
}
// in Exile
for (Card card : game.getState().getExile().getAllCards(game)) {
if (card.isCreature() && card.isOwnedBy(controller.getId())) {
card.setIsAllCreatureTypes(true);
}
}
// in Library (e.g. for Mystical Teachings)
for (Card card : controller.getLibrary().getCards(game)) {
if (card.isOwnedBy(controller.getId()) && card.isCreature()) {
card.setIsAllCreatureTypes(true);
}
}
// commander in command zone
for (CommandObject commandObject : game.getState().getCommand()) {
if (!(commandObject instanceof Commander)) {
continue;
}
Card card = game.getCard(((Commander) commandObject).getId());
if (card != null
&& card.isOwnedBy(controller.getId())
&& card.isCreature()) {
card.setIsAllCreatureTypes(true);
}
}
// creature spells you control
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
StackObject stackObject = iterator.next();
if (stackObject instanceof Spell
&& stackObject.isControlledBy(source.getControllerId())
&& stackObject.isCreature()) {
Card card = ((Spell) stackObject).getCard();
card.setIsAllCreatureTypes(true);
}
}
// creatures you control
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(
new FilterControlledCreaturePermanent(), source.getControllerId(), game);
for (Permanent creature : creatures) {
if (creature != null) {
creature.setIsAllCreatureTypes(true);
}
}
return true;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -0,0 +1,180 @@
package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.MultipliedValue;
import mage.abilities.dynamicvalue.common.CardsDrawnThisTurnDynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.token.ShardToken;
import mage.game.stack.Spell;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.watchers.Watcher;
import mage.watchers.common.CardsDrawnThisTurnWatcher;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class NikoAris extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("tapped creature");
static {
filter.add(TappedPredicate.instance);
}
private static final DynamicValue xValue = new MultipliedValue(CardsDrawnThisTurnDynamicValue.instance, 2);
public NikoAris(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{X}{W}{U}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.NIKO);
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// When Niko Aris enters the battlefield, create X Shard tokens.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new CreateTokenEffect(new ShardToken(), NikoArisValue.instance)
), new NikoArisWatcher());
// +1: Up to one target creature you control can't be blocked this turn. Whenever that creature deals damage this turn, return it to its owner's hand.
Ability ability = new LoyaltyAbility(new CantBeBlockedTargetEffect(Duration.EndOfTurn), 1);
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new NikoArisDamageTriggeredAbility()));
ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
this.addAbility(ability);
// 1: Niko Aris deals 2 damage to target tapped creature for each card you've drawn this turn.
ability = new LoyaltyAbility(new DamageTargetEffect(xValue).setText(
"{this} deals 2 damage to target tapped creature for each card you've drawn this turn"
), -1);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability, new CardsDrawnThisTurnWatcher());
// 1: Create a Shard token.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new ShardToken()), -1));
}
private NikoAris(final NikoAris card) {
super(card);
}
@Override
public NikoAris copy() {
return new NikoAris(this);
}
}
enum NikoArisValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
NikoArisWatcher watcher = game.getState().getWatcher(NikoArisWatcher.class, sourceAbility.getSourceId());
if (watcher == null) {
return 0;
}
if (game.getState().getValue(sourceAbility.getSourceId().toString() + "xValue") == null) {
return 0;
}
return (Integer) game.getState().getValue(sourceAbility.getSourceId().toString() + "xValue");
}
@Override
public DynamicValue copy() {
return instance;
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}
class NikoArisWatcher extends Watcher {
NikoArisWatcher() {
super(WatcherScope.CARD);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
return;
}
Spell spell = game.getSpellOrLKIStack(event.getTargetId());
if (spell == null || spell.getSourceId() != super.getSourceId()) {
return;
}
game.getState().setValue(
spell.getSourceId().toString() + "xValue",
spell.getSpellAbility().getManaCostsToPay().getX()
);
}
}
class NikoArisDamageTriggeredAbility extends DelayedTriggeredAbility {
NikoArisDamageTriggeredAbility() {
super(new ReturnToHandTargetEffect(), Duration.EndOfTurn, false);
}
private NikoArisDamageTriggeredAbility(final NikoArisDamageTriggeredAbility ability) {
super(ability);
}
@Override
public NikoArisDamageTriggeredAbility copy() {
return new NikoArisDamageTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
switch (event.getType()) {
case DAMAGED_PLAYER:
case DAMAGED_CREATURE:
case DAMAGED_PLANESWALKER:
return true;
}
return false;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return this.getEffects()
.stream()
.filter(Objects::nonNull)
.map(Effect::getTargetPointer)
.map(targetPointer -> targetPointer.getFirst(game, this))
.anyMatch(event.getSourceId()::equals);
}
@Override
public String getRule() {
return "Whenever that creature deals damage this turn, return it to its owner's hand.";
}
}

View file

@ -0,0 +1,103 @@
package mage.cards.p;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.BearToken;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
import java.util.Collection;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class PathToTheWorldTree extends CardImpl {
public PathToTheWorldTree(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
// When Path to the World Tree enters the battlefield, search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
)));
// {2}{W}{U}{B}{R}{G}, Sacrifice Path to the World Tree: You gain 2 life and draw two cards. Target opponent loses 2 life. Path to the World Tree deals 2 damage to up to one target creature. You create a 2/2 green Bear creature token.
Ability ability = new SimpleActivatedAbility(
new PathToTheWorldTreeEffect(), new ManaCostsImpl("{2}{W}{U}{B}{R}{G}")
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetOpponent());
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
}
private PathToTheWorldTree(final PathToTheWorldTree card) {
super(card);
}
@Override
public PathToTheWorldTree copy() {
return new PathToTheWorldTree(this);
}
}
class PathToTheWorldTreeEffect extends OneShotEffect {
PathToTheWorldTreeEffect() {
super(Outcome.Benefit);
staticText = "You gain 2 life and draw two cards. Target opponent loses 2 life. " +
"{this} deals 2 damage to up to one target creature. You create a 2/2 green Bear creature token.";
}
private PathToTheWorldTreeEffect(final PathToTheWorldTreeEffect effect) {
super(effect);
}
@Override
public PathToTheWorldTreeEffect copy() {
return new PathToTheWorldTreeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(2, game, source);
controller.drawCards(2, source, game);
}
for (UUID targetId : source
.getTargets()
.stream()
.map(Target::getTargets)
.flatMap(Collection::stream)
.collect(Collectors.toList())) {
Player player = game.getPlayer(targetId);
if (player != null) {
player.loseLife(2, game, source, false);
}
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(2, source.getSourceId(), source, game);
}
}
new BearToken().putOntoBattlefield(1, game, source, source.getControllerId());
return true;
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.s;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.counters.CounterType;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SnakeskinVeil extends CardImpl {
public SnakeskinVeil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
// Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
HexproofAbility.getInstance(), Duration.EndOfTurn
).setText("It gains hexproof until end of turn"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
}
private SnakeskinVeil(final SnakeskinVeil card) {
super(card);
}
@Override
public SnakeskinVeil copy() {
return new SnakeskinVeil(this);
}
}

View file

@ -0,0 +1,72 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterLandCard;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiritOfTheAldergard extends CardImpl {
private static final FilterCard filter
= new FilterLandCard("a snow land card");
private static final FilterPermanent filter2
= new FilterControlledPermanent("other snow permanent you control");
static {
filter.add(SuperType.SNOW.getPredicate());
filter2.add(SuperType.SNOW.getPredicate());
filter2.add(AnotherPredicate.instance);
}
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter2);
public SpiritOfTheAldergard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.addSuperType(SuperType.SNOW);
this.subtype.add(SubType.BEAR);
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
// When Spirit of the Aldergard enters the battlefield, search your library for a snow land card, reveal it, put it into your hand, then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true)
));
// Spirit of the Aldergard gets +1/+0 for each other snow permanent you control.
this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(
xValue, StaticValue.get(0), Duration.WhileOnBattlefield
)));
}
private SpiritOfTheAldergard(final SpiritOfTheAldergard card) {
super(card);
}
@Override
public SpiritOfTheAldergard copy() {
return new SpiritOfTheAldergard(this);
}
}

View file

@ -0,0 +1,70 @@
package mage.cards.v;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author weirddan455
*/
public final class VegaTheWatcher extends CardImpl {
public VegaTheWatcher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a spell from anywhere other than your hand, draw a card.
this.addAbility(new VegaTheWatcherTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
}
private VegaTheWatcher(final VegaTheWatcher card) {
super(card);
}
@Override
public VegaTheWatcher copy() {
return new VegaTheWatcher(this);
}
}
class VegaTheWatcherTriggeredAbility extends SpellCastControllerTriggeredAbility {
public VegaTheWatcherTriggeredAbility(Effect effect, boolean optional) {
super(effect, optional);
this.rule = "Whenever you cast a spell from anywhere other than your hand, draw a card.";
}
public VegaTheWatcherTriggeredAbility(final VegaTheWatcherTriggeredAbility ability) {
super(ability);
}
@Override
public VegaTheWatcherTriggeredAbility copy() {
return new VegaTheWatcherTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getZone() != Zone.HAND && super.checkTrigger(event, game);
}
}

View file

@ -19,6 +19,7 @@ public final class Kaldheim extends ExpansionSet {
"Cosmos Charger",
"Doomskar Oracle",
"Gods' Hall Guardian",
"Kaya's Onslaught",
"Quakebringer",
"Ranar the Ever-Watchful",
"Ravenform",
@ -48,6 +49,7 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Absorb Identity", 383, Rarity.UNCOMMON, mage.cards.a.AbsorbIdentity.class));
cards.add(new SetCardInfo("Alpine Meadow", 248, Rarity.COMMON, mage.cards.a.AlpineMeadow.class));
cards.add(new SetCardInfo("Alrund's Epiphany", 41, Rarity.MYTHIC, mage.cards.a.AlrundsEpiphany.class));
cards.add(new SetCardInfo("Annul", 42, Rarity.COMMON, mage.cards.a.Annul.class));
cards.add(new SetCardInfo("Arctic Treeline", 249, Rarity.COMMON, mage.cards.a.ArcticTreeline.class));
cards.add(new SetCardInfo("Armed and Armored", 379, Rarity.UNCOMMON, mage.cards.a.ArmedAndArmored.class));
cards.add(new SetCardInfo("Augury Raven", 44, Rarity.COMMON, mage.cards.a.AuguryRaven.class));
@ -56,6 +58,7 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Behold the Multiverse", 46, Rarity.COMMON, mage.cards.b.BeholdTheMultiverse.class));
cards.add(new SetCardInfo("Binding the Old Gods", 206, Rarity.UNCOMMON, mage.cards.b.BindingTheOldGods.class));
cards.add(new SetCardInfo("Blightstep Pathway", 252, Rarity.RARE, mage.cards.b.BlightstepPathway.class));
cards.add(new SetCardInfo("Bloodline Pretender", 235, Rarity.UNCOMMON, mage.cards.b.BloodlinePretender.class));
cards.add(new SetCardInfo("Bretagard Stronghold", 253, Rarity.UNCOMMON, mage.cards.b.BretagardStronghold.class));
cards.add(new SetCardInfo("Broken Wings", 164, Rarity.COMMON, mage.cards.b.BrokenWings.class));
cards.add(new SetCardInfo("Calamity Bearer", 125, Rarity.RARE, mage.cards.c.CalamityBearer.class));
@ -66,8 +69,10 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Elderfang Ritualist", 385, Rarity.UNCOMMON, mage.cards.e.ElderfangRitualist.class));
cards.add(new SetCardInfo("Elven Ambush", 391, Rarity.UNCOMMON, mage.cards.e.ElvenAmbush.class));
cards.add(new SetCardInfo("Elvish Warmaster", 167, Rarity.RARE, mage.cards.e.ElvishWarmaster.class));
cards.add(new SetCardInfo("Eradicator Valkyrie", 94, Rarity.MYTHIC, mage.cards.e.EradicatorValkyrie.class));
cards.add(new SetCardInfo("Esika's Chariot", 169, Rarity.RARE, mage.cards.e.EsikasChariot.class));
cards.add(new SetCardInfo("Esika, God of the Tree", 168, Rarity.MYTHIC, mage.cards.e.EsikaGodOfTheTree.class));
cards.add(new SetCardInfo("Faceless Haven", 255, Rarity.RARE, mage.cards.f.FacelessHaven.class));
cards.add(new SetCardInfo("Fire Giant's Fury", 389, Rarity.UNCOMMON, mage.cards.f.FireGiantsFury.class));
cards.add(new SetCardInfo("Firja, Judge of Valor", 209, Rarity.UNCOMMON, mage.cards.f.FirjaJudgeOfValor.class));
cards.add(new SetCardInfo("Forging the Tyrite Sword", 211, Rarity.UNCOMMON, mage.cards.f.ForgingTheTyriteSword.class));
@ -79,6 +84,8 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Gladewalker Ritualist", 392, Rarity.UNCOMMON, mage.cards.g.GladewalkerRitualist.class));
cards.add(new SetCardInfo("Gods' Hall Guardian", 13, Rarity.COMMON, mage.cards.g.GodsHallGuardian.class));
cards.add(new SetCardInfo("Goldspan Dragon", 139, Rarity.MYTHIC, mage.cards.g.GoldspanDragon.class));
cards.add(new SetCardInfo("Guardian Gladewalker", 174, Rarity.COMMON, mage.cards.g.GuardianGladewalker.class));
cards.add(new SetCardInfo("Hagi Mob", 140, Rarity.COMMON, mage.cards.h.HagiMob.class));
cards.add(new SetCardInfo("Hailstorm Valkyrie", 97, Rarity.UNCOMMON, mage.cards.h.HailstormValkyrie.class));
cards.add(new SetCardInfo("Halvar, God of Battle", 15, Rarity.MYTHIC, mage.cards.h.HalvarGodOfBattle.class));
cards.add(new SetCardInfo("Hengegate Pathway", 260, Rarity.RARE, mage.cards.h.HengegatePathway.class));
@ -87,10 +94,15 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Inga Rune-Eyes", 64, Rarity.UNCOMMON, mage.cards.i.IngaRuneEyes.class));
cards.add(new SetCardInfo("Invasion of the Giants", 215, Rarity.UNCOMMON, mage.cards.i.InvasionOfTheGiants.class));
cards.add(new SetCardInfo("Kaya the Inexorable", 218, Rarity.MYTHIC, mage.cards.k.KayaTheInexorable.class));
cards.add(new SetCardInfo("Kaya's Onslaught", 18, Rarity.UNCOMMON, mage.cards.k.KayasOnslaught.class));
cards.add(new SetCardInfo("Koll, the Forgemaster", 220, Rarity.UNCOMMON, mage.cards.k.KollTheForgemaster.class));
cards.add(new SetCardInfo("Koma's Faithful", 102, Rarity.COMMON, mage.cards.k.KomasFaithful.class));
cards.add(new SetCardInfo("Littjara Kinseekers", 66, Rarity.COMMON, mage.cards.l.LittjaraKinseekers.class));
cards.add(new SetCardInfo("Magda, Brazen Outlaw", 142, Rarity.RARE, mage.cards.m.MagdaBrazenOutlaw.class));
cards.add(new SetCardInfo("Masked Vandal", 184, Rarity.COMMON, mage.cards.m.MaskedVandal.class));
cards.add(new SetCardInfo("Maskwood Nexus", 240, Rarity.RARE, mage.cards.m.MaskwoodNexus.class));
cards.add(new SetCardInfo("Niko Aris", 225, Rarity.MYTHIC, mage.cards.n.NikoAris.class));
cards.add(new SetCardInfo("Path to the World Tree", 186, Rarity.UNCOMMON, mage.cards.p.PathToTheWorldTree.class));
cards.add(new SetCardInfo("Pyre of Heroes", 241, Rarity.RARE, mage.cards.p.PyreOfHeroes.class));
cards.add(new SetCardInfo("Rampage of the Valkyries", 393, Rarity.UNCOMMON, mage.cards.r.RampageOfTheValkyries.class));
cards.add(new SetCardInfo("Ravenform", 72, Rarity.COMMON, mage.cards.r.Ravenform.class));
@ -105,12 +117,14 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Seize the Spoils", 149, Rarity.COMMON, mage.cards.s.SeizeTheSpoils.class));
cards.add(new SetCardInfo("Showdown of the Skalds", 229, Rarity.RARE, mage.cards.s.ShowdownOfTheSkalds.class));
cards.add(new SetCardInfo("Sigrid, God-Favored", 29, Rarity.RARE, mage.cards.s.SigridGodFavored.class));
cards.add(new SetCardInfo("Snow-Covered Forest", 284, Rarity.COMMON, mage.cards.s.SnowCoveredForest.class));
cards.add(new SetCardInfo("Snow-Covered Island", 278, Rarity.COMMON, mage.cards.s.SnowCoveredIsland.class));
cards.add(new SetCardInfo("Snow-Covered Mountain", 282, Rarity.COMMON, mage.cards.s.SnowCoveredMountain.class));
cards.add(new SetCardInfo("Snow-Covered Plains", 276, Rarity.COMMON, mage.cards.s.SnowCoveredPlains.class));
cards.add(new SetCardInfo("Snow-Covered Swamp", 280, Rarity.COMMON, mage.cards.s.SnowCoveredSwamp.class));
cards.add(new SetCardInfo("Snakeskin Veil", 194, Rarity.COMMON, mage.cards.s.SnakeskinVeil.class));
cards.add(new SetCardInfo("Snow-Covered Forest", 284, Rarity.LAND, mage.cards.s.SnowCoveredForest.class));
cards.add(new SetCardInfo("Snow-Covered Island", 278, Rarity.LAND, mage.cards.s.SnowCoveredIsland.class));
cards.add(new SetCardInfo("Snow-Covered Mountain", 282, Rarity.LAND, mage.cards.s.SnowCoveredMountain.class));
cards.add(new SetCardInfo("Snow-Covered Plains", 276, Rarity.LAND, mage.cards.s.SnowCoveredPlains.class));
cards.add(new SetCardInfo("Snow-Covered Swamp", 280, Rarity.LAND, mage.cards.s.SnowCoveredSwamp.class));
cards.add(new SetCardInfo("Snowfield Sinkhole", 269, Rarity.COMMON, mage.cards.s.SnowfieldSinkhole.class));
cards.add(new SetCardInfo("Spirit of the Aldergard", 195, Rarity.UNCOMMON, mage.cards.s.SpiritOfTheAldergard.class));
cards.add(new SetCardInfo("Starnheim Aspirant", 380, Rarity.UNCOMMON, mage.cards.s.StarnheimAspirant.class));
cards.add(new SetCardInfo("Sulfurous Mine", 270, Rarity.COMMON, mage.cards.s.SulfurousMine.class));
cards.add(new SetCardInfo("Surtland Elementalist", 375, Rarity.RARE, mage.cards.s.SurtlandElementalist.class));
@ -123,6 +137,7 @@ public final class Kaldheim extends ExpansionSet {
cards.add(new SetCardInfo("Undersea Invader", 78, Rarity.COMMON, mage.cards.u.UnderseaInvader.class));
cards.add(new SetCardInfo("Valkyrie Harbinger", 374, Rarity.RARE, mage.cards.v.ValkyrieHarbinger.class));
cards.add(new SetCardInfo("Varragoth, Bloodsky Sire", 115, Rarity.RARE, mage.cards.v.VarragothBloodskySire.class));
cards.add(new SetCardInfo("Vega, the Watcher", 233, Rarity.UNCOMMON, mage.cards.v.VegaTheWatcher.class));
cards.add(new SetCardInfo("Village Rites", 117, Rarity.COMMON, mage.cards.v.VillageRites.class));
cards.add(new SetCardInfo("Volatile Fjord", 273, Rarity.COMMON, mage.cards.v.VolatileFjord.class));
cards.add(new SetCardInfo("Warchanter Skald", 381, Rarity.UNCOMMON, mage.cards.w.WarchanterSkald.class));

View file

@ -1,32 +0,0 @@
package mage.abilities.common;
import mage.abilities.StaticAbility;
import mage.abilities.effects.common.CantBeCounteredSourceEffect;
import mage.constants.Zone;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CantBeCounteredAbility extends StaticAbility {
public CantBeCounteredAbility() {
super(Zone.STACK, new CantBeCounteredSourceEffect());
}
public CantBeCounteredAbility(CantBeCounteredAbility ability) {
super(ability);
}
@Override
public String getRule() {
return "This spell can't be countered.";
}
@Override
public CantBeCounteredAbility copy() {
return new CantBeCounteredAbility(this);
}
}

View file

@ -4,6 +4,7 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
@ -14,8 +15,6 @@ import mage.target.targetpointer.FixedTarget;
*/
public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterSpell spellCard = new FilterSpell("a spell");
protected FilterSpell filter;
protected String rule;
@ -25,7 +24,7 @@ public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
protected boolean rememberSourceAsCard = false;
public SpellCastControllerTriggeredAbility(Effect effect, boolean optional) {
this(Zone.BATTLEFIELD, effect, spellCard, optional, false);
this(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_SPELL_A, optional, false);
}
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter, boolean optional) {

View file

@ -0,0 +1,47 @@
package mage.abilities.keyword;
import mage.MageObject;
import mage.game.Game;
import java.io.ObjectStreamException;
/**
* Hexproof from planesalkers
*
* @author weirddan455
*/
public class HexproofFromPlaneswalkersAbility extends HexproofBaseAbility {
private static final HexproofFromPlaneswalkersAbility instance;
static {
instance = new HexproofFromPlaneswalkersAbility();
}
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static HexproofFromPlaneswalkersAbility getInstance() {
return instance;
}
private HexproofFromPlaneswalkersAbility() {
super();
}
@Override
public boolean checkObject(MageObject source, Game game) {
return source.isPlaneswalker();
}
@Override
public HexproofFromPlaneswalkersAbility copy() {
return instance;
}
@Override
public String getRule() {
return "hexproof from planeswalkers";
}
}

View file

@ -33,6 +33,7 @@ public enum SubType {
CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType),
CURSE("Curse", SubTypeSet.EnchantmentType),
SAGA("Saga", SubTypeSet.EnchantmentType),
SHARD("Shard", SubTypeSet.EnchantmentType),
SHRINE("Shrine", SubTypeSet.EnchantmentType),
// 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types.
CLUE("Clue", SubTypeSet.ArtifactType),
@ -415,6 +416,7 @@ public enum SubType {
LUKKA("Lukka", SubTypeSet.PlaneswalkerType),
NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType),
NARSET("Narset", SubTypeSet.PlaneswalkerType),
NIKO("Niko", SubTypeSet.PlaneswalkerType),
NISSA("Nissa", SubTypeSet.PlaneswalkerType),
NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType),
OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars

View file

@ -0,0 +1,31 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.abilities.keyword.ChangelingAbility;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author TheElk801
*/
public final class ShapeshifterBlueToken extends TokenImpl {
public ShapeshifterBlueToken() {
super("Shapeshifter", "2/2 blue Shapeshifter creature token with changeling");
cardType.add(CardType.CREATURE);
subtype.add(SubType.SHAPESHIFTER);
color.setBlue(true);
power = new MageInt(2);
toughness = new MageInt(2);
setIsAllCreatureTypes(true);
addAbility(ChangelingAbility.getInstance());
}
private ShapeshifterBlueToken(final ShapeshifterBlueToken token) {
super(token);
}
public ShapeshifterBlueToken copy() {
return new ShapeshifterBlueToken(this);
}
}

View file

@ -0,0 +1,39 @@
package mage.game.permanent.token;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author TheElk801
*/
public final class ShardToken extends TokenImpl {
public ShardToken() {
super("Shard", "Shard token");
cardType.add(CardType.ENCHANTMENT);
subtype.add(SubType.SHARD);
// {2}, Sacrifice this enchantment: Scry 1, then draw a card.
Ability ability = new SimpleActivatedAbility(new ScryEffect(1), new GenericManaCost(2));
ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy(", then"));
SacrificeSourceCost cost = new SacrificeSourceCost();
cost.setText("Sacrifice this enchantment");
ability.addCost(cost);
this.addAbility(ability);
}
public ShardToken(final ShardToken token) {
super(token);
}
public ShardToken copy() {
return new ShardToken(this);
}
}

View file

@ -40023,20 +40023,25 @@ Doomskar Oracle|Kaldheim|10|C|{2}{W}|Creature - Human Cleric|3|2|Whenever you ca
Gods' Hall Guardian|Kaldheim|13|C|{5}{W}|Creature - Cat|3|6|Vigilance$Foretell {3}{W}|
Halvar, God of Battle|Kaldheim|15|M|{2}{W}{W}|Legendary Creature - God|4|4|Creatures you control that are enchanted or equipped have double strike.$At the beginning of each combat, you may attach target Aura or Equipment attached to a creature you control to target creature you control.|
Sword of the Realms|Kaldheim|15|M|{1}{W}|Legendary Artifact - Equipment|||Equipped creature gets +2/+0 and has vigilance.$Whenever equipped creature dies, return it to its owner's hand.$Equip {1}{W}|
Kaya's Onslaught|Kaldheim|18|U|{2}{W}|Instant|||Target creature gets +1/+1 and gains double strike until end of turn.$Foretell {W}|
Sigrid, God-Favored|Kaldheim|29|R|{1}{W}{W}|Legendary Creature - Human Warrior|2|2|Flash$First strike, protection from God creatures$When Sigrid, God-Favored enters the battlefield, exile up to one target attacking or blocking creature until Sigrid leaves the battlefield.|
Alrund, God of the Cosmos|Kaldheim|40|M|{3}{U}{U}|Legendary Creature - God|1|1|Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile.$At the beginning of your end step, choose a card type, then reveal the top two cards of your library. Put all cards of the chosen type into your hand and the rest on the bottom of your library in any order.|
Hakka, Whispering Raven|Kaldheim|40|M|{1}{U}|Legendary Creature - Bird|2|3|Flying$Whenever Hakka, Whispering Raven deals combat damage to a player, return it to its owner's hand, then scry 2.|
Alrund's Epiphany|Kaldheim|41|M|{5}{U}{U}|Sorcery|||Create two 1/1 blue Bird creature tokens with flying. Take an extra turn after this one. Exile Alrund's Epiphany.$Foretell {4}{U}{U}|
Annul|Kaldheim|42|C|{U}|Instant|||Counter target artifact or enchantment spell.|
Augury Raven|Kaldheim|44|C|{3}{U}|Creature - Bird|3|3|Flying$Foretell {1}{U}|
Behold the Multiverse|Kaldheim|46|C|{3}{U}|Instant|||Scry 2, then draw two cards.$Foretell {1}{U}|
Cosmos Charger|Kaldheim|51|R|{3}{U}|Creature - Horse Spirit|3|3|Flash$Flying$Foretelling cards from your hand costs {1} less and can be done on any player's turn.$Foretell {2}{U}|
Giant's Amulet|Kaldheim|59|U|{U}|Artifact - Equipment|||When Giant's Amulet enters the battlefield, you may pay {3}{U}. If you do, create a 4/4 blue Giant Wizard creature token, then attach Giant's Amulet to it.$Equipped creature gets +0/+1 and has "This creature has hexproof as long as it's untapped."$Equip {2}|
Glimpse the Cosmos|Kaldheim|60|U|{1}{U}|Sorcery|||Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.$As long as you control a Giant, you may cast Glimpse the Cosmos from your graveyard by paying {U} rather than paying its mana cost. If you cast Glimpse the Cosmos this way and it would be put into your graveyard, exile it instead.|
Inga Rune-Eyes|Kaldheim|64|U|{3}{U}|Legendary Creature - Human Wizard|3|3|When Inga Rune-Eyes enters the battlefield, scry 3.$When Inga Rune-Eyes dies, draw three cards if three or more creatures died this turn.|
Littjara Kinseekers|Kaldheim|66|C|{3}{U}|Creature - Shapeshifter|2|4|Changeling$When Littjara Kinseekers enters the battlefield, if you control three or more creatures that share a creature type, put a +1/+1 counter on Littjara Kinseekers, then scry 1.|
Ravenform|Kaldheim|72|C|{2}{U}|Sorcery|||Exile target artifact or creature. Its controller creates a 1/1 blue Bird creature token with flying.$Foretell {U}|
Reflections of Littjara|Kaldheim|73|R|{4}{U}|Enchantment|||As Reflections of Littjara enters the battlefield, choose a creature type.$Whenever you cast a spell of the chosen type, copy that spell.|
Saw It Coming|Kaldheim|76|U|{1}{U}{U}|Instant|||Counter target spell.$Foretell {1}{U}|
Undersea Invader|Kaldheim|78|C|{4}{U}{U}|Creature - Giant Rogue|5|6|Flash$Undersea Invader enters the battlefield tapped.|
Draugr Necromancer|Kaldheim|86|R|{3}{B}|Snow Creature - Zombie Cleric|4|4|If a nontoken creature an opponent controls would die, exile that card with an ice counter on it instead.$You may cast spells from among cards in exile your opponents own with ice counters on them, and you may spend mana from snow sources as though it were mana of any color to cast those spells.|
Eradicator Valkyrie|Kaldheim|94|M|{2}{B}{B}|Creature - Angel Berserker|4|3|Flying, lifelink, hexproof from planeswalkers$Boast — {1}{B}, Sacrifice a creature: Each opponent sacrifices a creature or planeswalker.|
Hailstorm Valkyrie|Kaldheim|97|U|{3}{B}|Snow Creature - Angel Wizard|2|2|Flying, trample${S}{S}: Hailstorm Valkyrie gets +2/+2 until end of turn.|
Koma's Faithful|Kaldheim|102|C|{2}{B}|Creature - Elf Cleric|3|1|Lifelink$When Koma's Faithful dies, each player mills three cards.|
Tergrid's Lantern|Kaldheim|112|R|{3}{B}|Legendary Artifact|||{T}: Target player loses 3 life unless they sacrifice a nonland permanent or discard a card.${3}{B}: Untap Tergrid's Lantern.|
@ -40048,15 +40053,17 @@ Village Rites|Kaldheim|117|C|{B}|Instant|||As an additional cost to cast this sp
Calamity Bearer|Kaldheim|125|R|{2}{R}{R}|Creature - Giant Berserker|3|4|If a Giant source you control would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.|
Frost Bite|Kaldheim|138|C|{R}|Snow Instant|||Frost Bite deals 2 damage to target creature or planeswalker. If you control three or more snow permanents, it deals 3 damage instead.|
Goldspan Dragon|Kaldheim|139|M|{3}{R}{R}|Creature - Dragon|4|4|Flying, haste$Whenever Goldspan Dragon attacks or becomes the target of a spell, create a Treasure token.$Treasures you control have "{T}, Sacrifice this artifact: Add two mana of any one color."|
Hagi Mob|Kaldheim|140|C|{4}{R}|Creature - Troll Berserker|5|4|Boast — {1}{R}: Hagi Mob deals 1 damage to any target.|
Magda, Brazen Outlaw|Kaldheim|142|R|{1}{R}|Legendary Creature - Dwarf Berserker|2|1|Other Dwarves you control get +1/+0.$Whenever a Dwarf you control becomes tapped, create a Treasure token.$Sacrifice five Treasures: Search your library for an artifact or Dragon card, put that card onto the battlefield, then shuffle your library.|
Quakebringer|Kaldheim|145|M|{3}{R}{R}|Creature - Giant Berserker|5|4|Your opponents can't gain life.$At the beginning of your upkeep, Quakebringer deals 2 damage to each opponent. This ability triggers only if Quakebringer is on the battlefield or if Quakebringer is in your graveyard and you control a Giant.$Foretell {2}{R}{R}|
Reckless Crew|Kaldheim|148|R|{3}{R}|Sorcery|||Create X 2/1 red Dwarf creature tokenswhere X is the number of Vehicles you control plus the number of Equipment you control.$For each of those tokens, You may attach an Equipment you control to it.|
Reckless Crew|Kaldheim|148|R|{3}{R}|Sorcery|||Create X 2/1 red Dwarf creature tokens, where X is the number of Vehicles you control plus the number of Equipments you control. For each of those tokens, you may attach an Equipment you control to it.|
Seize the Spoils|Kaldheim|149|C|{2}{R}|Sorcery|||As an additional cost to cast this spell, discard a card.$Draw two cards and create a Treasure token.|
Broken Wings|Kaldheim|164|C|{2}{G}|Instant|||Destroy target artifact, enchantment, or creature with flying.|
Elvish Warmaster|Kaldheim|167|R|{1}{G}|Creature - Elf Warrior|2|2|Whenever one or more other Elves enters the battlefield under your control, create a 1/1 green Elf Warrior creature token. This ability triggers only once each turn.${5}{G}{G}: Elves you control get +2/+2 and gain deathtouch until end of turn.|
Esika, God of the Tree|Kaldheim|168|M|{1}{G}{G}|Legendary Creature - God|1|4|Vigilance${T}: Add one mana of any color.$Other legendary creatures you control have vigilance and "{T}: Add one mana of any color."|
The Prismatic Bridge|Kaldheim|168|M|{W}{U}{B}{R}{G}|Legendary Enchantment|||At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature or planeswalker card. Put that card onto the battlefield and the rest on the bottom of your library in a random order.|
Esika's Chariot|Kaldheim|169|R|{3}{G}|Legendary Artifact - Vehicle|4|4|When Esika's Chariot enters the battlefield, create two 2/2 green Cat creature tokens.$Whenever Esika's Chariot attacks, create a token that's a copy of target token you control.$Crew 4|
Guardian Gladewalker|Kaldheim|174|C|{1}{G}|Creature - Shapeshifter|1|1|Changeling$When Guardian Gladewalker enters the battlefield, put a +1/+1 counter on target creature.|
Kolvori, God of Kinship|Kaldheim|181|R|{2}{G}{G}|Legendary Creature - God|2|4|As long as you control three or more legendary creatures, Kolvori, God of Kinship gets +4/+2 and has vigilance.${1}{G}, {T}: Look at the top six cards of your library. You may reveal a legendary creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.|
The Ringheart Crest|Kaldheim|181|R|{1}{G}|Legendary Artifact|||As The Ringheart Crest enters the battlefield, choose a creature type.${T}: Add {G}. Spend this mana only to cast a creature spell of the chosen type or a legendary creature spell.|
Masked Vandal|Kaldheim|184|C|{1}{G}|Creature - Shapeshifter|1|3|Changeling$When Masked Vandal enters the battlefield, you may exile a creature card from your graveyard. If you do, exile target artifact or enchantment an opponent controls.|
@ -40065,6 +40072,7 @@ Path to the World Tree|Kaldheim|186|U|{1}{G}|Enchantment|||When Path to the Worl
Realmwalker|Kaldheim|188|R|{2}{G}|Creature - Shapeshifter|2|3|Changeling$As Realmwalker enters the battlefield, choose a creature type.$You may look at the top card of your library any time.$You may cast creature spells of the chosen type from the top of your library.|
Sarulf's Packmate|Kaldheim|192|C|{3}{G}|Creature - Wolf|3|3|When Sarulf's Packmate enters the battlefield, draw a card.$Foretell {1}{G}|
Sculptor of Winter|Kaldheim|193|C|{1}{G}|Snow Creature - Elf Rogue|2|2|{T}: Untap target snow land.|
Snakeskin Veil|Kaldheim|194|C|{G}|Instant|||Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.|
Spirit of the Aldergard|Kaldheim|195|U|{3}{G}|Snow Creature - Bear Spirit|0|4|When Spirit of the Aldergard enters the battlefield, search your library for a snow land card, reveal it, put it into your hand, then shuffle your library.$Spirit of the Aldergard gets +1/+0 for each other snow permanent you control.|
Toski, Bearer of Secrets|Kaldheim|197|R|{3}{G}|Legendary Creature - Squirrel|1|1|This spell can't be countered.$Indestructible$Toski, Bearer of Secrets attacks each combat if able.$Whenever a creature you control deals combat damage to a player, draw a card.|
Vorinclex, Monstrous Raider|Kaldheim|199|M|{4}{G}{G}|Legendary Creature - Phyrexian Praetor|6|6|Trample, haste$If you would put one or more counters on a permanent or player, put twice that many of each of those kinds of counters on that permanent or player instead.$If an opponent would put one or more counters on a permanent or player, they put half that many of each of those kinds of counters on that permanent or player instead, rounded down.|
@ -40080,6 +40088,8 @@ Sarulf, Realm Eater|Kaldheim|228|R|{1}{B}{G}|Legendary Creature - Wolf|3|3|Whene
Showdown of the Skalds|Kaldheim|229|R|{2}{R}{W}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Exile the top four cards of your library. Until the end of your next turn, you may play those cards.$II, III — Whenever you cast a spell this turn, put a +1/+1 counter on target creature you control.|
The Trickster-God's Heist|Kaldheim|232|U|{2}{U}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — You may exchange control of two target creatures.$II — You may exchange control of two target nonbasic, noncreature permanents that share a card type.$III — Target player loses 3 life and you gain 3 life.|
Vega, the Watcher|Kaldheim|233|U|{1}{W}{U}|Legendary Creature - Bird Spirit|2|2|Flying$Whenever you cast a spell from anywhere other than your hand, draw a card.|
Bloodline Pretender|Kaldheim|235|U|{3}|Artifact Creature - Shapeshifter|2|2|Changeling$As Bloodline Pretender enters the battlefield, choose a creature type.$Whenever another creature of the chosen type enters the battlefield under your control, put a +1/+1 counter on Bloodline Pretender.|
Maskwood Nexus|Kaldheim|240|R|{4}|Artifact|||Creatures you control are every creature type. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.${3}, {T}: Create a 2/2 blue Shapeshifter creature token with changeling.|
Pyre of Heroes|Kaldheim|241|R|{2}|Artifact|||{2}, {T}, Sacrifice a creature: Search your library for a creature card that shares a creature type with the sacrificed creature and has converted mana cost equal to 1 plus that creature's converted mana cost. Put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.|
Replicating Ring|Kaldheim|244|U|{3}|Snow Artifact|||{T}: Add one mana of any color.$At the beginning of your upkeep, put a night counter on Replicating Ring. Then if it has eight or more night counters on it, remove all of them and create eight colorless snow artifact tokens named Replicated Ring with "{T}: Add one mana of any color."|
Alpine Meadow|Kaldheim|248|C||Snow Land - Mountain Plains|||({T}: Add {R} or {W}.)$Alpine Meadow enters the battlefield tapped.|
@ -40091,6 +40101,7 @@ Searstep Pathway|Kaldheim|252|R||Land|||{T}: Add {R}.|
Bretagard Stronghold|Kaldheim|253|U||Land|||Bretagard Stronghold enters the battlefield tapped.${T}: Add {G}.${G}{W}{W}, {T}, Sacrifice Bretagard Stronghold: Put a +1/+1 counter on each of up to two target creatures you control. They gain vigilance and lifelink until end of turn. Activate this ability only any time you cast a sorcery.|
Darkbore Pathway|Kaldheim|254|R||Land|||{T}: Add {B}.|
Slitherbore Pathway|Kaldheim|254|R||Land|||{T}: Add {G}.|
Faceless Haven|Kaldheim|255|R||Snow Land|||{T}: Add {C}.${S}{S}{S}: Faceless Haven becomes a 4/3 creature with vigilance and all creature types until end of turn. It's still a land.|
Glacial Floodplain|Kaldheim|257|C||Snow Land - Plains Island|||({T}: Add {W} or {U}.)$Glacial Floodplain enters the battlefield tapped.|
Hengegate Pathway|Kaldheim|260|R||Land|||{T}: Add {W}.|
Mistgate Pathway|Kaldheim|260|R||Land|||{T}: Add {U}.|