Merge branch 'master' into feature/implement-waterbending-mechanic

This commit is contained in:
theelk801 2025-12-18 09:40:54 -05:00
commit 1f1dd1218a
359 changed files with 9726 additions and 10022 deletions

View file

@ -618,6 +618,8 @@ public class ScryfallImageSupportCards {
add("ECL"); // Lorwyn Eclipsed
add("TMT"); // Teenage Mutant Ninja Turtles
add("TMC"); // Teenage Mutant Ninja Turtles Eternal
add("MSH"); // Marvel Super Heroes
add("MSC"); // Marvel Super Heroes Commander
// Custom sets using Scryfall images - must provide a direct link for each card in directDownloadLinks
add("CALC"); // Custom Alchemized versions of existing cards

View file

@ -1,51 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author fireshoes
*/
public final class AbolisherOfBloodlines extends CardImpl {
public AbolisherOfBloodlines(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.VAMPIRE);
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// this card is the second face of double-faced card
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// When this creature transforms into Abolisher of Bloodlines, target opponent sacrifices three creatures.
Ability ability = new TransformIntoSourceTriggeredAbility(new SacrificeEffect(
StaticFilters.FILTER_PERMANENT_CREATURES, 3, "target opponent"
));
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
private AbolisherOfBloodlines(final AbolisherOfBloodlines card) {
super(card);
}
@Override
public AbolisherOfBloodlines copy() {
return new AbolisherOfBloodlines(this);
}
}

View file

@ -42,7 +42,7 @@ public final class AllOutAssault extends CardImpl {
extraCombatAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new WhenYouAttackDelayedTriggeredAbility(
new UntapAllControllerEffect(
StaticFilters.FILTER_CONTROLLED_CREATURE, "untap each creature you control"), Duration.EndOfTurn, true)));
this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOUR));
this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOURS));
}

View file

@ -117,7 +117,7 @@ enum WretchedBonemassDynamicValue implements DynamicValue {
ExileZone exileZone = game
.getExile()
.getExileZone(CardUtil.getExileZoneId(
game, permanent.getId(), permanent.getZoneChangeCounter(game) - 2
game, permanent.getMainCard().getId(), permanent.getZoneChangeCounter(game) - 1
));
if (exileZone == null) {
return 0;
@ -167,7 +167,7 @@ class WretchedBonemassGainAbilityEffect extends ContinuousEffectImpl {
ExileZone exileZone = game
.getExile()
.getExileZone(CardUtil.getExileZoneId(
game, wretchedBonemass.getId(), wretchedBonemass.getZoneChangeCounter(game) - 2
game, wretchedBonemass.getMainCard().getId(), wretchedBonemass.getZoneChangeCounter(game) - 1
));
if (exileZone != null
&& !exileZone.isEmpty()) {

View file

@ -1,92 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.card.DefendingPlayerOwnsCardPredicate;
import mage.game.Game;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class AnimusOfNightsReach extends CardImpl {
private static final FilterCard filter
= new FilterCreatureCard("creature cards in defending player's graveyard");
static {
filter.add(DefendingPlayerOwnsCardPredicate.instance);
}
private static final DynamicValue xValue = new CardsInAllGraveyardsCount(filter);
public AnimusOfNightsReach(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
this.color.setBlack(true);
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility());
// Whenever Animus of Night's Reach attacks, it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard.
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
xValue, StaticValue.get(0), Duration.EndOfTurn
).setText("it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard")).addHint(AnimusOfNightsReachHint.instance));
}
private AnimusOfNightsReach(final AnimusOfNightsReach card) {
super(card);
}
@Override
public AnimusOfNightsReach copy() {
return new AnimusOfNightsReach(this);
}
}
enum AnimusOfNightsReachHint implements Hint {
instance;
@Override
public String getText(Game game, Ability ability) {
return "Cards in each opponent's graveyard:<br>"
+ game
.getOpponents(ability.getControllerId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(player -> player
.getName()
+ ": " + player
.getGraveyard()
.count(StaticFilters.FILTER_CARD_CREATURE, game))
.collect(Collectors.joining("<br>"));
}
@Override
public AnimusOfNightsReachHint copy() {
return instance;
}
}

View file

@ -1,45 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.permanent.token.SpiritToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ArchitectOfRestoration extends CardImpl {
public ArchitectOfRestoration(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.FOX);
this.subtype.add(SubType.MONK);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
this.color.setWhite(true);
this.nightCard = true;
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever Architect of Restoration attacks or blocks, create a 1/1 colorless Spirit creature token.
this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false));
}
private ArchitectOfRestoration(final ArchitectOfRestoration card) {
super(card);
}
@Override
public ArchitectOfRestoration copy() {
return new ArchitectOfRestoration(this);
}
}

View file

@ -0,0 +1,76 @@
package mage.cards.a;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.common.TransformsOrEntersTriggeredAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.mana.AddConditionalManaOfAnyColorEffect;
import mage.abilities.mana.conditional.ConditionalSpellManaBuilder;
import mage.abilities.meta.OrTriggeredAbility;
import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AshlingRekindled extends TransformingDoubleFacedCard {
private static final FilterSpell filter = new FilterSpell("spells with mana value 4 or greater");
static {
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
}
public AshlingRekindled(UUID ownerId, CardSetInfo setInfo) {
super(
ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL, SubType.SORCERER}, "{1}{R}",
"Ashling, Rimebound",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL, SubType.WIZARD}, "U"
);
this.getLeftHalfCard().setPT(1, 3);
this.getRightHalfCard().setPT(1, 3);
// Whenever this creature enters or transforms into Ashling, Rekindled, you may discard a card. If you do, draw a card.
this.getLeftHalfCard().addAbility(new TransformsOrEntersTriggeredAbility(
new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()), false
));
// At the beginning of your first main phase, you may pay {U}. If you do, transform Ashling.
this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility(
new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{U}"))
));
// Ashling, Rimebound
// Whenever this creature transforms into Ashling, Rimebound and at the beginning of your first main phase, add two mana of any one color. Spend this mana only to cast spells with mana value 4 or greater.
this.getRightHalfCard().addAbility(new OrTriggeredAbility(
Zone.BATTLEFIELD,
new AddConditionalManaOfAnyColorEffect(2, new ConditionalSpellManaBuilder(filter)),
new TransformIntoSourceTriggeredAbility(null),
new BeginningOfFirstMainTriggeredAbility(null)
));
// At the beginning of your first main phase, you may pay {R}. If you do, transform Ashling.
this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility(
new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{R}"))
));
}
private AshlingRekindled(final AshlingRekindled card) {
super(card);
}
@Override
public AshlingRekindled copy() {
return new AshlingRekindled(this);
}
}

View file

@ -1,50 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AshmouthDragon extends CardImpl {
public AshmouthDragon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.DRAGON);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.color.setRed(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast an instant or sorcery spell, Ashmouth Dragon deals 2 damage to any target.
Ability ability = new SpellCastControllerTriggeredAbility(
new DamageTargetEffect(2), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private AshmouthDragon(final AshmouthDragon card) {
super(card);
}
@Override
public AshmouthDragon copy() {
return new AshmouthDragon(this);
}
}

View file

@ -0,0 +1,51 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AttumaAtlanteanWarlord extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(SubType.MERFOLK);
public AttumaAtlanteanWarlord(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.MERFOLK);
this.subtype.add(SubType.WARRIOR);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// Other Merfolk you control get +1/+1.
this.addAbility(new SimpleStaticAbility(new BoostAllEffect(
1, 1, Duration.WhileOnBattlefield, filter, true
)));
// Whenever one or more Merfolk you control attack a player, draw a card.
this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility(
new DrawCardSourceControllerEffect(1), filter, SetTargetPointer.NONE
));
}
private AttumaAtlanteanWarlord(final AttumaAtlanteanWarlord card) {
super(card);
}
@Override
public AttumaAtlanteanWarlord copy() {
return new AttumaAtlanteanWarlord(this);
}
}

View file

@ -1,50 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.costs.common.WaterbendCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
import mage.abilities.keyword.ExhaustAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.permanent.token.SpiritWorldToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarKuruk extends CardImpl {
public AvatarKuruk(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
this.nightCard = true;
// Whenever you cast a spell, create a 1/1 colorless Spirit creature token with "This token can't block or be blocked by non-Spirit creatures."
this.addAbility(new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new SpiritWorldToken()), StaticFilters.FILTER_SPELL_A, false
));
// Exhaust -- Waterbend {20}: Take an extra turn after this one.
this.addAbility(new ExhaustAbility(new AddExtraTurnControllerEffect(), new WaterbendCost(20)));
}
private AvatarKuruk(final AvatarKuruk card) {
super(card);
}
@Override
public AvatarKuruk copy() {
return new AvatarKuruk(this);
}
}

View file

@ -1,62 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.common.GreatestAmongPermanentsValue;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.mana.DynamicManaAbility;
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.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarKyoshi extends CardImpl {
public AvatarKyoshi(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
this.nightCard = true;
// Lands you control have trample and hexproof.
Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS
));
ability.addEffect(new GainAbilityControlledEffect(
HexproofAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS
).setText("and hexproof"));
this.addAbility(ability);
// {T}: Add X mana of any one color, where X is the greatest power among creatures you control.
this.addAbility(new DynamicManaAbility(
Mana.AnyMana(1), GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES,
new TapSourceCost(), "add X mana of any one color, " +
"where X is the greatest power among creatures you control", true
).addHint(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES.getHint()));
}
private AvatarKyoshi(final AvatarKyoshi card) {
super(card);
}
@Override
public AvatarKyoshi copy() {
return new AvatarKyoshi(this);
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.FirebendingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.game.permanent.token.DragonFirebendingToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarRoku extends CardImpl {
public AvatarRoku(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.nightCard = true;
// Firebending 4
this.addAbility(new FirebendingAbility(4));
// {8}: Create a 4/4 red Dragon creature token with flying and firebending 4.
this.addAbility(new SimpleActivatedAbility(
new CreateTokenEffect(new DragonFirebendingToken()), new GenericManaCost(8)
));
}
private AvatarRoku(final AvatarRoku card) {
super(card);
}
@Override
public AvatarRoku copy() {
return new AvatarRoku(this);
}
}

View file

@ -1,57 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.CastSecondSpellTriggeredAbility;
import mage.abilities.effects.keyword.AirbendTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarYangchen extends CardImpl {
private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent");
static {
filter.add(AnotherPredicate.instance);
}
public AvatarYangchen(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast your second spell each turn, airbend up to one other target nonland permanent.
Ability ability = new CastSecondSpellTriggeredAbility(new AirbendTargetEffect());
ability.addTarget(new TargetPermanent(0, 1, filter));
this.addAbility(ability);
}
private AvatarYangchen(final AvatarYangchen card) {
super(card);
}
@Override
public AvatarYangchen copy() {
return new AvatarYangchen(this);
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import java.util.UUID;
/**
* @author fireshoes
*/
public final class AwokenHorror extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Horror creatures");
static {
filter.add(Predicates.not(SubType.HORROR.getPredicate()));
}
public AwokenHorror(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.KRAKEN);
this.subtype.add(SubType.HORROR);
this.power = new MageInt(7);
this.toughness = new MageInt(8);
this.color.setBlue(true);
this.nightCard = true;
// When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.
this.addAbility(new TransformIntoSourceTriggeredAbility(new ReturnToHandFromBattlefieldAllEffect(filter)));
}
private AwokenHorror(final AwokenHorror card) {
super(card);
}
@Override
public AwokenHorror copy() {
return new AwokenHorror(this);
}
}

View file

@ -1,60 +0,0 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.PutCards;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
/**
*
* @author LevelX2
*/
public final class AzcantaTheSunkenRuin extends CardImpl {
private static final FilterCard filter = new FilterCard("a noncreature, nonland card");
static {
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public AzcantaTheSunkenRuin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
// this card is the second face of double-faced card
this.nightCard = true;
// (Transforms from Search for Azcanta)/
// {T} : Add {U}.
this.addAbility(new BlueManaAbility());
// {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
Ability ability = new SimpleActivatedAbility(
new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY),
new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private AzcantaTheSunkenRuin(final AzcantaTheSunkenRuin card) {
super(card);
}
@Override
public AzcantaTheSunkenRuin copy() {
return new AzcantaTheSunkenRuin(this);
}
}

View file

@ -4,7 +4,7 @@ import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.condition.common.MorbidCondition;
import mage.abilities.condition.common.YouControlPermanentCondition;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.GetXValue;
@ -16,8 +16,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import java.util.UUID;
@ -26,21 +24,14 @@ import java.util.UUID;
*/
public final class BaradDur extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature");
static {
filter.add(SuperType.LEGENDARY.getPredicate());
}
private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter);
public BaradDur(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
// Barad-dur enters the battlefield tapped unless you control a legendary creature.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint()));
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance)
.addHint(YouControlALegendaryCreatureCondition.getHint()));
// {T}: Add {B}.
this.addAbility(new BlackManaAbility());

View file

@ -1,56 +0,0 @@
package mage.cards.b;
import mage.abilities.common.CastSpellPaidBySourceTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.game.permanent.token.GnomeSoldierStarStarToken;
import java.util.UUID;
/**
* @author Susucr
*/
public final class BarracksOfTheThousand extends CardImpl {
private static final FilterSpell filter = new FilterSpell("an artifact or creature spell");
static {
filter.add(Predicates.or(
CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate()
));
}
public BarracksOfTheThousand(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
// (Transforms from Thousand Moons Smithy.)
this.nightCard = true;
// {T}: Add {W}.
this.addAbility(new WhiteManaAbility());
// Whenever you cast an artifact or creature spell using mana produced by Barracks of the Thousand, create a white Gnome Soldier artifact creature token with "This creature's power and toughness are each equal to the number of artifacts and/or creatures you control."
this.addAbility(new CastSpellPaidBySourceTriggeredAbility(
new CreateTokenEffect(new GnomeSoldierStarStarToken()),
filter, false
));
}
private BarracksOfTheThousand(final BarracksOfTheThousand card) {
super(card);
}
@Override
public BarracksOfTheThousand copy() {
return new BarracksOfTheThousand(this);
}
}

View file

@ -19,7 +19,7 @@ import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.WallToken;
import mage.game.permanent.token.BasaltGolemToken;
import mage.players.Player;
/**
@ -30,7 +30,7 @@ public final class BasaltGolem extends CardImpl {
public BasaltGolem(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
@ -83,6 +83,6 @@ class BasaltGolemEffect extends OneShotEffect {
if (!creature.sacrifice(source, game))
return false;
return new WallToken().putOntoBattlefield(1, game, source, player.getId());
return new BasaltGolemToken().putOntoBattlefield(1, game, source, player.getId());
}
}

View file

@ -1,54 +0,0 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.LandfallAbility;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BlackChocobo extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.BIRD, "Birds");
public BlackChocobo(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.BIRD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.nightCard = true;
this.color.setGreen(true);
// When this permanent transforms into Black Chocobo, search your library for a land card, put it onto the battlefield tapped, then shuffle.
this.addAbility(new TransformIntoSourceTriggeredAbility(
new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND_A), true)
));
// Landfall -- Whenever a land you control enters, Birds you control get +1/+0 until end of turn.
this.addAbility(new LandfallAbility(new BoostControlledEffect(
1, 0, Duration.EndOfTurn, filter, false
)));
}
private BlackChocobo(final BlackChocobo card) {
super(card);
}
@Override
public BlackChocobo copy() {
return new BlackChocobo(this);
}
}

View file

@ -1,68 +0,0 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.permanent.token.custom.CreatureToken;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BloodbatSummoner extends CardImpl {
private static final FilterPermanent filter
= new FilterControlledPermanent(SubType.BLOOD, "Blood token you control");
static {
filter.add(TokenPredicate.TRUE);
}
public BloodbatSummoner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.color.setBlack(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// At the beginning of combat on your turn, up to one target Blood token you control becomes a 2/2 black Bat creature with flying and haste in addition to its other types.
Ability ability = new BeginningOfCombatTriggeredAbility(new BecomesCreatureTargetEffect(
new CreatureToken(2, 2, "", SubType.BAT)
.withAbility(FlyingAbility.getInstance())
.withAbility(HasteAbility.getInstance())
.withColor("B"),
false, false, Duration.Custom
).setText("up to one target Blood token you control becomes a " +
"2/2 black Bat creature with flying and haste in addition to its other types"));
ability.addTarget(new TargetPermanent(0, 1, filter));
this.addAbility(ability);
}
private BloodbatSummoner(final BloodbatSummoner card) {
super(card);
}
@Override
public BloodbatSummoner copy() {
return new BloodbatSummoner(this);
}
}

View file

@ -1,47 +0,0 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.keyword.NightboundAbility;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BlossomCladWerewolf extends CardImpl {
public BlossomCladWerewolf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
this.color.setGreen(true);
this.nightCard = true;
// {T}: Add two mana of any one color.
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost()
));
// Nightbound
this.addAbility(new NightboundAbility());
}
private BlossomCladWerewolf(final BlossomCladWerewolf card) {
super(card);
}
@Override
public BlossomCladWerewolf copy() {
return new BlossomCladWerewolf(this);
}
}

View file

@ -26,8 +26,7 @@ public final class BottomlessPoolLockerRoom extends RoomCard {
// Enchantment -- Room
// Whenever one or more creatures you control deal combat damage to a player, draw a card.
super(ownerId, setInfo,
new CardType[] { CardType.ENCHANTMENT },
"{U}", "{4}{U}", SpellAbilityType.SPLIT);
"{U}", "{4}{U}");
this.subtype.add(SubType.ROOM);
// Left half ability - "When you unlock this door, return up to one target creature to its owners hand."
@ -52,4 +51,4 @@ public final class BottomlessPoolLockerRoom extends RoomCard {
public BottomlessPoolLockerRoom copy() {
return new BottomlessPoolLockerRoom(this);
}
}
}

View file

@ -0,0 +1,82 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
import mage.abilities.condition.common.SourceAttackingCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.common.AdditionalCombatPhaseEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.UntapSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardSetInfo;
import mage.cards.ModalDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BruceBanner extends ModalDoubleFacedCard {
public BruceBanner(UUID ownerId, CardSetInfo setInfo) {
super(
ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SCIENTIST, SubType.HERO}, "{U}",
"The Incredible Hulk",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GAMMA, SubType.BERSERKER, SubType.HERO}, "{2}{R}{R}{G}{G}"
);
this.getLeftHalfCard().setPT(1, 1);
this.getRightHalfCard().setPT(8, 8);
// {X}{X}, {T}: Draw X cards. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
new DrawCardSourceControllerEffect(GetXValue.instance), new ManaCostsImpl<>("{X}{X}")
);
ability.addCost(new TapSourceCost());
this.getLeftHalfCard().addAbility(ability);
// {2}{R}{R}{G}{G}: Transform Bruce Banner. Activate only as a sorcery.
this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}{R}{G}{G}")
));
// The Incredible Hulk
// Reach
this.getRightHalfCard().addAbility(ReachAbility.getInstance());
// Trample
this.getRightHalfCard().addAbility(TrampleAbility.getInstance());
// Enrage -- Whenever The Incredible Hulk is dealt damage, put a +1/+1 counter on him. If he's attacking, untap him and there is an additional combat phase after this phase.
ability = new DealtDamageToSourceTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
.setText("put a +1/+1 counter on him"),
false, true
);
ability.addEffect(new ConditionalOneShotEffect(
new UntapSourceEffect(), SourceAttackingCondition.instance, "If he's attacking, " +
"untap him and there is an additional combat phase after this phase"
).addEffect(new AdditionalCombatPhaseEffect()));
this.getRightHalfCard().addAbility(ability);
}
private BruceBanner(final BruceBanner card) {
super(card);
}
@Override
public BruceBanner copy() {
return new BruceBanner(this);
}
}

View file

@ -1,41 +0,0 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BurnishedDunestomper extends CardImpl {
public BurnishedDunestomper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.DOG);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
this.color.setWhite(true);
this.color.setGreen(true);
this.nightCard = true;
// Trample
this.addAbility(TrampleAbility.getInstance());
}
private BurnishedDunestomper(final BurnishedDunestomper card) {
super(card);
}
@Override
public BurnishedDunestomper copy() {
return new BurnishedDunestomper(this);
}
}

View file

@ -0,0 +1,72 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.HexproofAbility;
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.counters.CounterType;
import mage.filter.FilterPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CaptainAmericaSuperSoldier extends CardImpl {
private static final Condition condition = new SourceHasCounterCondition(CounterType.SHIELD);
private static final FilterPermanent filter = new FilterPermanent(SubType.HERO, "Heroes");
public CaptainAmericaSuperSoldier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Captain America enters with a shield counter on him.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.SHIELD.createInstance()),
"with a shield counter on him"
));
// As long as Captain America has a shield counter on him, you and other Heroes you control have hexproof.
Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilityControllerEffect(HexproofAbility.getInstance()),
condition, "as long as {this} has a shield counter on him, you"
));
ability.addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(
HexproofAbility.getInstance(), Duration.WhileOnBattlefield, filter, true
), condition, null).concatBy("and"));
this.addAbility(ability);
}
private CaptainAmericaSuperSoldier(final CaptainAmericaSuperSoldier card) {
super(card);
}
@Override
public CaptainAmericaSuperSoldier copy() {
return new CaptainAmericaSuperSoldier(this);
}
}

View file

@ -1,19 +1,25 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandCard;
import mage.target.common.TargetCardInLibrary;
@ -22,37 +28,59 @@ import java.util.UUID;
/**
* @author TheElk801
*/
public final class CasalLurkwoodPathfinder extends CardImpl {
public final class CasalLurkwoodPathfinder extends TransformingDoubleFacedCard {
private static final FilterLandCard filter = new FilterLandCard("Forest card");
private static final FilterCreaturePermanent filterLegendary = new FilterCreaturePermanent();
static {
filter.add(SubType.FOREST.getPredicate());
filterLegendary.add(SuperType.LEGENDARY.getPredicate());
}
public CasalLurkwoodPathfinder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.TIEFLING, SubType.DRUID}, "{3}{G}",
"Casal, Pathbreaker Owlbear",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BIRD, SubType.BEAR}, "G"
);
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.TIEFLING);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.secondSideCardClazz = CasalPathbreakerOwlbear.class;
// Casal, Lurkwood Pathfinder
this.getLeftHalfCard().setPT(3, 3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance());
// When Doric, Nature's Warden enters the battlefield, search your library for a Forest card, put it into the battlefield tapped, then shuffle.
this.addAbility(new EntersBattlefieldTriggeredAbility(
// When Casal, Lurkwood Pathfinder enters the battlefield, search your library for a Forest card, put it into the battlefield tapped, then shuffle.
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(
new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true)
));
// Whenever Doric attacks, you may pay {1}{G}. If you do, transform her.
this.addAbility(new TransformAbility());
this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
// Whenever Casal attacks, you may pay {1}{G}. If you do, transform her.
this.getLeftHalfCard().addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
new TransformSourceEffect().setText("transform her"), new ManaCostsImpl<>("{1}{G}")
)));
// Casal, Pathbreaker Owlbear
this.getRightHalfCard().setPT(6, 6);
// Vigilance
this.getRightHalfCard().addAbility(VigilanceAbility.getInstance());
// Trample
this.getRightHalfCard().addAbility(TrampleAbility.getInstance());
// When this creature transforms into Casal, Pathbreaker Owlbear, other legendary creatures you control get +2/+2 and gain trample until end of turn.
Ability ability = new TransformIntoSourceTriggeredAbility(new BoostControlledEffect(
2, 2, Duration.EndOfTurn, filterLegendary, true
).setText("other legendary creatures you control get +2/+2"));
ability.addEffect(new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn, filterLegendary, true
).setText("and gain trample until end of turn"));
this.getRightHalfCard().addAbility(ability);
// At the beginning of your upkeep, transform Casal.
this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()));
}
private CasalLurkwoodPathfinder(final CasalLurkwoodPathfinder card) {

View file

@ -1,68 +0,0 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CasalPathbreakerOwlbear extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(SuperType.LEGENDARY.getPredicate());
}
public CasalPathbreakerOwlbear(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.BEAR);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
this.color.setGreen(true);
this.nightCard = true;
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// When this creature transforms into Doric, Owlbear Avenger, other legendary creatures you control get +2/+2 and gain trample until end of turn.
Ability ability = new TransformIntoSourceTriggeredAbility(new BoostControlledEffect(
2, 2, Duration.EndOfTurn, filter, true
).setText("other legendary creatures you control get +2/+2"));
ability.addEffect(new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn, filter, true
).setText("and gain trample until end of turn"));
this.addAbility(ability);
// At the beginning of your upkeep, transform Doric.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()));
}
private CasalPathbreakerOwlbear(final CasalPathbreakerOwlbear card) {
super(card);
}
@Override
public CasalPathbreakerOwlbear copy() {
return new CasalPathbreakerOwlbear(this);
}
}

View file

@ -0,0 +1,62 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.mana.BasicManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreatureSpell;
import mage.game.permanent.token.ChocoboToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ChocoboCamp extends CardImpl {
private static final FilterSpell filter = new FilterCreatureSpell("a Bird creature spell");
static {
filter.add(SubType.BIRD.getPredicate());
}
public ChocoboCamp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped unless you control a legendary creature.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance)
.addHint(YouControlALegendaryCreatureCondition.getHint()));
// {T}: Add {G}. When you next cast a Bird creature spell this turn, it enters with an additional +1/+1 counter on it.
BasicManaAbility manaAbility = new GreenManaAbility();
manaAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new AddCounterNextSpellDelayedTriggeredAbility(filter)));
manaAbility.setUndoPossible(false);
this.addAbility(manaAbility);
// {2}{G}{G}, {T}: Create a 2/2 green Bird creature token with "Whenever a land you control enters, this token gets +1/+0 until end of turn."
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new ChocoboToken()), new ManaCostsImpl<>("{2}{G}{G}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private ChocoboCamp(final ChocoboCamp card) {
super(card);
}
@Override
public ChocoboCamp copy() {
return new ChocoboCamp(this);
}
}

View file

@ -1,50 +0,0 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CipherboundSpirit extends CardImpl {
public CipherboundSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
this.color.setBlue(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Cipherbound Spirit can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
// {3}{U}: Draw two cards, then discard a card.
this.addAbility(new SimpleActivatedAbility(
new DrawDiscardControllerEffect(2, 1), new ManaCostsImpl<>("{3}{U}")
));
}
private CipherboundSpirit(final CipherboundSpirit card) {
super(card);
}
@Override
public CipherboundSpirit copy() {
return new CipherboundSpirit(this);
}
}

View file

@ -1,39 +0,0 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ConsumingSepulcher extends CardImpl {
public ConsumingSepulcher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.nightCard = true;
this.color.setBlack(true);
// At the beginning of your upkeep, each opponent loses 1 life and you gain 1 life.
Ability ability = new BeginningOfUpkeepTriggeredAbility(
new LoseLifeOpponentsEffect(1)
);
ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(ability);
}
private ConsumingSepulcher(final ConsumingSepulcher card) {
super(card);
}
@Override
public ConsumingSepulcher copy() {
return new ConsumingSepulcher(this);
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
/**
* @author balazskristof
*/
public final class CookingCampsite extends CardImpl {
public CookingCampsite(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.nightCard = true;
// {T}: Add {W}.
this.addAbility(new WhiteManaAbility());
// {3}, {T}, Sacrifice an artifact: Put a +1/+1 counter on each creature you control. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE), new ManaCostsImpl<>("{3}")
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT_AN));
this.addAbility(ability);
}
private CookingCampsite(final CookingCampsite card) {
super(card);
}
@Override
public CookingCampsite copy() {
return new CookingCampsite(this);
}
}

View file

@ -1,98 +0,0 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
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.players.Player;
import mage.target.Target;
import mage.target.common.TargetCardInExile;
import mage.util.CardUtil;
/**
* Cosmium Catalyst
* Artifact
* {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost.
*
* @author DominionSpy
*/
public class CosmiumCatalyst extends CardImpl {
public CosmiumCatalyst(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.nightCard = true;
this.color.setRed(true);
// {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost.
Ability ability = new SimpleActivatedAbility(new CosmiumCatalystEffect(), new ManaCostsImpl<>("{1}{R}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private CosmiumCatalyst(CosmiumCatalyst card) {
super(card);
}
@Override
public CosmiumCatalyst copy() {
return new CosmiumCatalyst(this);
}
}
class CosmiumCatalystEffect extends OneShotEffect {
CosmiumCatalystEffect() {
super(Outcome.PlayForFree);
this.staticText = "Choose an exiled card used to craft {this} at random." +
" You may cast that card without paying its mana cost.";
}
private CosmiumCatalystEffect(CosmiumCatalystEffect effect) {
super(effect);
}
@Override
public CosmiumCatalystEffect copy() {
return new CosmiumCatalystEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
MageObject sourceObject = game.getObject(source.getSourceId());
if (sourceObject == null) {
return false;
}
Target target = new TargetCardInExile(StaticFilters.FILTER_CARD,
CardUtil.getExileZoneId(game, source.getSourceId(),
game.getState().getZoneChangeCounter(source.getSourceId()) - 2
));
target.withNotTarget(true);
target.setRandom(true);
if (!target.canChoose(controller.getId(), source, game)) {
return true;
}
target.chooseTarget(outcome, controller.getId(), source, game);
Card chosenCard = game.getCard(target.getFirstTarget());
if (chosenCard != null) {
CardUtil.castSpellWithAttributesForFree(controller, source, game, chosenCard);
}
return true;
}
}

View file

@ -1,45 +0,0 @@
package mage.cards.c;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.s.SerahFarron;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CrystallizedSerah extends CardImpl {
public CrystallizedSerah(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.supertype.add(SuperType.LEGENDARY);
this.nightCard = true;
this.color.setGreen(true);
this.color.setWhite(true);
// The first legendary creature spell you cast each turn costs {2} less to cast.
this.addAbility(SerahFarron.makeAbility());
// Legendary creatures you control get +2/+2.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
2, 2, Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURES_LEGENDARY
)));
}
private CrystallizedSerah(final CrystallizedSerah card) {
super(card);
}
@Override
public CrystallizedSerah copy() {
return new CrystallizedSerah(this);
}
}

View file

@ -8,7 +8,6 @@ import mage.abilities.keyword.ConvokeAbility;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.CardType;
import mage.constants.SpellAbilityType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterNonlandCard;
@ -30,7 +29,7 @@ public final class DazzlingTheaterPropRoom extends RoomCard {
}
public DazzlingTheaterPropRoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}", "{2}{W}", SpellAbilityType.SPLIT);
super(ownerId, setInfo, "{3}{W}", "{2}{W}");
this.subtype.add(SubType.ROOM);
// Dazzling Theater: Creature spells you cast have convoke.

View file

@ -0,0 +1,45 @@
package mage.cards.d;
import mage.abilities.Ability;
import mage.abilities.common.CardsLeaveGraveyardTriggeredAbility;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.filter.StaticFilters;
import mage.game.permanent.token.HorrorEnchantmentCreatureToken;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefiledCryptCadaverLab extends RoomCard {
public DefiledCryptCadaverLab(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{3}{B}", "{B}");
// Defiled Crypt
// Whenever one or more cards leave your graveyard, create a 2/2 black Horror enchantment creature token. This ability triggers only once each turn.
this.getLeftHalfCard().addAbility(new CardsLeaveGraveyardTriggeredAbility(
new CreateTokenEffect(new HorrorEnchantmentCreatureToken())
).setTriggersLimitEachTurn(1));
// Cadaver Lab
// When you unlock this door, return target creature card from your graveyard to your hand.
Ability ability = new UnlockThisDoorTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false, false);
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.getRightHalfCard().addAbility(ability);
}
private DefiledCryptCadaverLab(final DefiledCryptCadaverLab card) {
super(card);
}
@Override
public DefiledCryptCadaverLab copy() {
return new DefiledCryptCadaverLab(this);
}
}

View file

@ -0,0 +1,52 @@
package mage.cards.d;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAloneControlledTriggeredAbility;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DerelictAtticWidowsWalk extends RoomCard {
public DerelictAtticWidowsWalk(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{B}", "{3}{B}");
// Derelict Attic
// When you unlock this door, you draw two cards and you lose 2 life.
Ability ability = new UnlockThisDoorTriggeredAbility(
new DrawCardSourceControllerEffect(2, true), false, true
);
ability.addEffect(new LoseLifeSourceControllerEffect(2).concatBy("and"));
this.getLeftHalfCard().addAbility(ability);
// Widow's Walk
// Whenever a creature you control attacks alone, it gets +1/+0 and gains deathtouch until end of turn.
ability = new AttacksAloneControlledTriggeredAbility(
new BoostTargetEffect(1, 0).setText("it gets +1/+0"),
StaticFilters.FILTER_CONTROLLED_A_CREATURE, true, false
);
ability.addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance())
.setText("and gains deathtouch until end of turn"));
this.getRightHalfCard().addAbility(ability);
}
private DerelictAtticWidowsWalk(final DerelictAtticWidowsWalk card) {
super(card);
}
@Override
public DerelictAtticWidowsWalk copy() {
return new DerelictAtticWidowsWalk(this);
}
}

View file

@ -1,59 +0,0 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlaneswalkerPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DireStrainAnarchist extends CardImpl {
public DireStrainAnarchist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
this.color.setRed(true);
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility(false));
// Haste
this.addAbility(HasteAbility.getInstance());
// Whenever Dire-Strain Anarchist attacks, it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker.
Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(2).setText("it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker"));
ability.addTarget(new TargetCreaturePermanent(0, 1));
ability.addTarget(new TargetPlayer(0, 1, false));
ability.addTarget(new TargetPlaneswalkerPermanent(0, 1));
this.addAbility(ability);
// Nightbound
this.addAbility(new NightboundAbility());
}
private DireStrainAnarchist(final DireStrainAnarchist card) {
super(card);
}
@Override
public DireStrainAnarchist copy() {
return new DireStrainAnarchist(this);
}
}

View file

@ -1,42 +0,0 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.keyword.NightboundAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DireStrainBrawler extends CardImpl {
public DireStrainBrawler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
this.color.setGreen(true);
this.nightCard = true;
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Nightbound
this.addAbility(new NightboundAbility());
}
private DireStrainBrawler(final DireStrainBrawler card) {
super(card);
}
@Override
public DireStrainBrawler copy() {
return new DireStrainBrawler(this);
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
@ -9,15 +9,18 @@ import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.game.permanent.token.HumanWizardToken;
@ -27,7 +30,7 @@ import java.util.UUID;
/**
* @author fireshoes
*/
public final class DocentOfPerfection extends CardImpl {
public final class DocentOfPerfection extends TransformingDoubleFacedCard {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
new FilterControlledPermanent(SubType.WIZARD), ComparisonType.MORE_THAN, 2
@ -35,22 +38,27 @@ public final class DocentOfPerfection extends CardImpl {
private static final Hint hint = new ValueHint(
"Wizards you control", new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.WIZARD))
);
private static final FilterPermanent filterWizard = new FilterPermanent("Wizards");
static {
filterWizard.add(SubType.WIZARD.getPredicate());
}
public DocentOfPerfection(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.HORROR);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.INSECT, SubType.HORROR}, "{3}{U}{U}",
"Final Iteration",
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.INSECT}, ""
);
this.secondSideCardClazz = mage.cards.f.FinalIteration.class;
// Docent of Perfection
this.getLeftHalfCard().setPT(5, 4);
// Flying
this.addAbility(FlyingAbility.getInstance());
this.getLeftHalfCard().addAbility(FlyingAbility.getInstance());
// Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token.
// Then if you control three or more Wizards, transform Docent of Perfection.
this.addAbility(new TransformAbility());
Ability ability = new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new HumanWizardToken()),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
@ -59,7 +67,28 @@ public final class DocentOfPerfection extends CardImpl {
new TransformSourceEffect(), condition,
"Then if you control three or more Wizards, transform {this}"
));
this.addAbility(ability.addHint(hint));
this.getLeftHalfCard().addAbility(ability.addHint(hint));
// Final Iteration
this.getRightHalfCard().setPT(6, 5);
// Flying
this.getRightHalfCard().addAbility(FlyingAbility.getInstance());
// Wizards you control get +2/+1 and have flying.
Ability ability2 = new SimpleStaticAbility(new BoostControlledEffect(
2, 1, Duration.WhileOnBattlefield, filterWizard, false
));
ability2.addEffect(new GainAbilityControlledEffect(
FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filterWizard
).setText("and have flying"));
this.getRightHalfCard().addAbility(ability2);
// Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token.
this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new HumanWizardToken()),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
));
}
private DocentOfPerfection(final DocentOfPerfection card) {

View file

@ -0,0 +1,83 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.game.permanent.token.DoombotToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DoctorDoom extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent("you control an artifact creature or a Plan");
static {
filter.add(Predicates.or(
Predicates.and(
CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate()
),
SubType.PLAN.getPredicate()
));
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
private static final Hint hint = new ConditionHint(condition);
public DoctorDoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCIENTIST);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When Doctor Doom enters, create two 3/3 colorless Robot Villain artifact creature tokens named Doombot.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new DoombotToken(), 2)));
// As long as you control an artifact creature or a Plan, Doctor Doom has indestructible.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), condition,
"as long as you control an artifact creature or a Plan, {this} has indestructible"
)).addHint(hint));
// At the beginning of your end step, you draw a card and lose 1 life.
Ability ability = new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1, true));
ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and"));
this.addAbility(ability);
}
private DoctorDoom(final DoctorDoom card) {
super(card);
}
@Override
public DoctorDoom copy() {
return new DoctorDoom(this);
}
}

View file

@ -9,7 +9,9 @@ import mage.abilities.effects.common.continuous.SetBasePowerToughnessAllEffect;
import mage.abilities.hint.ValueHint;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.*;
import mage.constants.Duration;
import mage.constants.SetTargetPointer;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
@ -29,7 +31,7 @@ public final class DollmakersShopPorcelainGallery extends RoomCard {
}
public DollmakersShopPorcelainGallery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}", "{4}{W}{W}", SpellAbilityType.SPLIT);
super(ownerId, setInfo, "{1}{W}", "{4}{W}{W}");
this.subtype.add(SubType.ROOM);
// Dollmaker's Shop: Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.
@ -44,7 +46,7 @@ public final class DollmakersShopPorcelainGallery extends RoomCard {
this.getRightHalfCard().addAbility(right);
}
private DollmakersShopPorcelainGallery (final DollmakersShopPorcelainGallery card) {
private DollmakersShopPorcelainGallery(final DollmakersShopPorcelainGallery card) {
super(card);
}

View file

@ -0,0 +1,39 @@
package mage.cards.d;
import mage.abilities.condition.common.IsMainPhaseCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.keyword.BlightControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DoseOfDawnglow extends CardImpl {
public DoseOfDawnglow(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
// Return target creature card from your graveyard to the battlefield. Then if it isn't your main phase, blight 2.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new BlightControllerEffect(2), IsMainPhaseCondition.NOT_YOURS
).concatBy("Then"));
}
private DoseOfDawnglow(final DoseOfDawnglow card) {
super(card);
}
@Override
public DoseOfDawnglow copy() {
return new DoseOfDawnglow(this);
}
}

View file

@ -36,7 +36,7 @@ public final class DovinsAcuity extends CardImpl {
// Whenever you cast an instant spell during your main phase, you may return Dovin's Acuity to its owner's hand.
this.addAbility(new SpellCastControllerTriggeredAbility(
new ReturnToHandSourceEffect(true), filter, true
).withTriggerCondition(IsMainPhaseCondition.YOUR).setTriggerPhrase("Whenever you cast an instant spell during your main phase, "));
).withTriggerCondition(IsMainPhaseCondition.YOURS).setTriggerPhrase("Whenever you cast an instant spell during your main phase, "));
}
private DovinsAcuity(final DovinsAcuity card) {

View file

@ -1,91 +0,0 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesThisOrAnotherTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DragonKamisEgg extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON);
public DragonKamisEgg(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.EGG);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
this.color.setGreen(true);
this.nightCard = true;
// Whenever Dragon-Kami's Egg or a Dragon you control dies, you may cast a creature spell from among cards you own in exile with hatching counters on them without paying its mana cost.
this.addAbility(new DiesThisOrAnotherTriggeredAbility(
new DragonKamisEggEffect(), false, filter
).setTriggerPhrase("Whenever {this} or a Dragon you control dies, "));
}
private DragonKamisEgg(final DragonKamisEgg card) {
super(card);
}
@Override
public DragonKamisEgg copy() {
return new DragonKamisEgg(this);
}
}
class DragonKamisEggEffect extends OneShotEffect {
DragonKamisEggEffect() {
super(Outcome.Benefit);
staticText = "you may cast a creature spell from among cards you own in exile " +
"with hatching counters on them without paying its mana cost";
}
private DragonKamisEggEffect(final DragonKamisEggEffect effect) {
super(effect);
}
@Override
public DragonKamisEggEffect copy() {
return new DragonKamisEggEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl();
game.getExile()
.getCardsOwned(game, player.getId())
.stream()
.filter(Objects::nonNull)
.filter(card -> card.getCounters(game).containsKey(CounterType.HATCHLING))
.forEach(cards::add);
return !cards.isEmpty() && CardUtil.castSpellWithAttributesForFree(
player, source, game, cards, StaticFilters.FILTER_CARD_CREATURE
);
}
}

View file

@ -1,47 +0,0 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.effects.common.MillCardsControllerEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DreadOsseosaur extends CardImpl {
public DreadOsseosaur(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.DINOSAUR);
this.subtype.add(SubType.SKELETON);
this.subtype.add(SubType.HORROR);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
this.nightCard = true;
this.color.setBlack(true);
// Menace
this.addAbility(new MenaceAbility(false));
// Whenever Dread Osseosaur enters the battlefield or attacks, you may mill two cards.
this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(
new MillCardsControllerEffect(2), true
));
}
private DreadOsseosaur(final DreadOsseosaur card) {
super(card);
}
@Override
public DreadOsseosaur copy() {
return new DreadOsseosaur(this);
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author fireshoes
*/
public final class DronepackKindred extends CardImpl {
public DronepackKindred(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(5);
this.toughness = new MageInt(7);
// this card is the second face of double-faced card
this.nightCard = true;
// Trample
this.addAbility(TrampleAbility.getInstance());
// {1}: Dronepack Kindred gets +1/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(1)));
}
private DronepackKindred(final DronepackKindred card) {
super(card);
}
@Override
public DronepackKindred copy() {
return new DronepackKindred(this);
}
}

View file

@ -1,67 +0,0 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainControlAllEffect;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.TokenPredicate;
/**
*
* @author weirddan455
*/
public final class EchoOfDeathsWail extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.RAT, "Rat tokens");
static {
filter.add(TokenPredicate.TRUE);
}
public EchoOfDeathsWail(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.color.setBlack(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// When Echo of Death's Wail enters the battlefield, gain control of all Rat tokens.
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainControlAllEffect(Duration.Custom, filter)));
// Whenever Echo of Death's Wail attacks, you may sacrifice another creature. If you do, draw a card.
this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
new DrawCardSourceControllerEffect(1),
new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)
)));
}
private EchoOfDeathsWail(final EchoOfDeathsWail card) {
super(card);
}
@Override
public EchoOfDeathsWail copy() {
return new EchoOfDeathsWail(this);
}
}

View file

@ -1,45 +0,0 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetAnyTarget;
/**
*
* @author fireshoes
*/
public final class EruptingDreadwolf extends CardImpl {
public EruptingDreadwolf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(6);
this.toughness = new MageInt(4);
// this card is the second face of double-faced card
this.nightCard = true;
// Whenever Erupting Dreadwolf attacks, it deals 2 damage to any target.
Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(2, "it"), false);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private EruptingDreadwolf(final EruptingDreadwolf card) {
super(card);
}
@Override
public EruptingDreadwolf copy() {
return new EruptingDreadwolf(this);
}
}

View file

@ -1,125 +0,0 @@
package mage.cards.e;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledEnchantmentPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class EsperTerra extends CardImpl {
private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("nonlegendary enchantment you control");
static {
filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate()));
}
public EsperTerra(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SAGA);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
this.nightCard = true;
this.color.setRed(true);
this.color.setGreen(true);
// (As this Saga enters and after your draw step, add a lore counter.)
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_IV);
// I, II, III -- Create a token that's a copy of target nonlegendary enchantment you control. It gains haste. If it's a Saga, put up to three lore counters on it. Sacrifice it at the beginning of your next end step.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_III,
new EsperTerraEffect(), new TargetPermanent(filter)
);
// IV -- Add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}. Exile Esper Terra, then return it to the battlefield.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_IV,
new BasicManaEffect(new Mana(
2, 2, 2, 2, 2, 0, 0, 0
)).setText("add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}"),
new ExileSourceAndReturnFaceUpEffect());
this.addAbility(sagaAbility);
// Flying
this.addAbility(FlyingAbility.getInstance());
}
private EsperTerra(final EsperTerra card) {
super(card);
}
@Override
public EsperTerra copy() {
return new EsperTerra(this);
}
}
class EsperTerraEffect extends OneShotEffect {
EsperTerraEffect() {
super(Outcome.Benefit);
staticText = "create a token that's a copy of target nonlegendary enchantment you control. " +
"It gains haste. If it's a Saga, put up to three lore counters on it. " +
"Sacrifice it at the beginning of your next end step";
}
private EsperTerraEffect(final EsperTerraEffect effect) {
super(effect);
}
@Override
public EsperTerraEffect copy() {
return new EsperTerraEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
return false;
}
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect();
effect.setSavedPermanent(permanent);
effect.addAdditionalAbilities(HasteAbility.getInstance());
effect.apply(game, source);
for (Permanent token : effect.getAddedPermanents()) {
if (!token.hasSubtype(SubType.SAGA, game)) {
continue;
}
Optional.ofNullable(source.getControllerId())
.map(game::getPlayer)
.map(player -> player.getAmount(
0, 3, "Choose how many lore counters to put on " + token.getIdName(), source, game
))
.filter(amount -> amount > 0)
.ifPresent(amount -> token.addCounters(CounterType.LORE.createInstance(amount), source, game));
}
effect.removeTokensCreatedAt(game, source, false, PhaseStep.END_TURN, TargetController.YOU);
return true;
}
}

View file

@ -3,14 +3,12 @@ package mage.cards.e;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.CostAdjuster;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -27,11 +25,6 @@ import java.util.UUID;
*/
public final class EsquireOfTheKing extends CardImpl {
private static final Hint hint = new ConditionHint(
new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY),
"You control a legendary creature"
);
public EsquireOfTheKing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
@ -47,7 +40,7 @@ public final class EsquireOfTheKing extends CardImpl {
ability.addCost(new TapSourceCost());
ability.setCostAdjuster(EsquireOfTheKingAdjuster.instance);
ability.addEffect(new InfoEffect("This ability costs {2} less to activate if you control a legendary creature."));
this.addAbility(ability.addHint(hint));
this.addAbility(ability.addHint(YouControlALegendaryCreatureCondition.getHint()));
}
private EsquireOfTheKing(final EsquireOfTheKing card) {

View file

@ -0,0 +1,80 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.keyword.ManifestDreadEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.Outcome;
import mage.constants.SetTargetPointer;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ExperimentalLabStaffRoom extends RoomCard {
public ExperimentalLabStaffRoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{3}{G}", "{2}{G}");
// Experimental Lab
// When you unlock this door, manifest dread, then put two +1/+1 counters and a trample counter on that creature.
this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new ManifestDreadEffect(
CounterType.P1P1.createInstance(2), CounterType.TRAMPLE.createInstance()
), false, true));
// Staff Room
// Whenever a creature you control deals combat damage to a player, turn that creature face up or put a +1/+1 counter on it.
this.getRightHalfCard().addAbility(new DealsDamageToAPlayerAllTriggeredAbility(
new StaffRoomEffect(), StaticFilters.FILTER_CONTROLLED_CREATURE,
false, SetTargetPointer.PERMANENT, true
));
}
private ExperimentalLabStaffRoom(final ExperimentalLabStaffRoom card) {
super(card);
}
@Override
public ExperimentalLabStaffRoom copy() {
return new ExperimentalLabStaffRoom(this);
}
}
class StaffRoomEffect extends OneShotEffect {
StaffRoomEffect() {
super(Outcome.Benefit);
staticText = "turn that creature face up or put a +1/+1 counter on it";
}
private StaffRoomEffect(final StaffRoomEffect effect) {
super(effect);
}
@Override
public StaffRoomEffect copy() {
return new StaffRoomEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null) {
return false;
}
return permanent.isFaceDown(game)
&& player.chooseUse(Outcome.BoostCreature, "Turn " + permanent.getIdName() + " creature face-up?", source, game)
&& permanent.turnFaceUp(source, game, source.getControllerId())
|| permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
}
}

View file

@ -2,14 +2,15 @@ package mage.cards.e;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.CraftAbility;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.Card;
@ -27,6 +28,7 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
import mage.util.CardUtil;
import mage.watchers.common.SpellsCastWatcher;
import java.util.*;
import java.util.stream.Collectors;
@ -149,7 +151,10 @@ class ChooseCardTypeEffect extends OneShotEffect {
if (permanent == null) {
return false;
}
ExileZone exileZone = game.getState().getExile().getExileZone(CardUtil.getExileZoneId(game, source, game.getState().getZoneChangeCounter(mageObject.getId()) - 1));
ExileZone exileZone = game.getState()
.getExile()
.getExileZone(CardUtil
.getExileZoneId(game, permanent.getMainCard().getId(), permanent.getMainCard().getZoneChangeCounter(game)));
if (exileZone == null) {
return false;
}
@ -232,63 +237,74 @@ class ApexObservatoryEffect extends OneShotEffect {
}
}
class ApexObservatoryCastWithoutManaEffect extends CostModificationEffectImpl {
class ApexObservatoryCastWithoutManaEffect extends ContinuousEffectImpl {
class ApexObservatoryCondition implements Condition {
private final int spellCastCount;
private ApexObservatoryCondition(int spellCastCount) {
this.spellCastCount = spellCastCount;
}
@Override
public boolean apply(Game game, Ability source) {
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
if (watcher != null) {
return watcher.getSpellsCastThisTurn(playerId).size() == spellCastCount;
}
return false;
}
}
private final FilterCard filter;
private final String chosenCardType;
private final UUID playerId;
private boolean used = false;
private int spellCastCount;
private AlternativeCostSourceAbility alternativeCostSourceAbility;
ApexObservatoryCastWithoutManaEffect(String chosenCardType, UUID playerId) {
super(Duration.EndOfTurn, Outcome.Benefit, CostModificationType.SET_COST);
super(Duration.EndOfTurn, Layer.RulesEffects, SubLayer.NA, Outcome.PlayForFree);
this.chosenCardType = chosenCardType;
this.playerId = playerId;
this.filter = new FilterCard("spell of the chosen type");
filter.add(CardType.fromString(chosenCardType).getPredicate());
staticText = "The next spell you cast this turn of the chosen type can be cast without paying its mana cost";
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
if (watcher != null) {
spellCastCount = watcher.getSpellsCastThisTurn(playerId).size();
Condition condition = new ApexObservatoryCondition(spellCastCount);
alternativeCostSourceAbility = new AlternativeCostSourceAbility(
null, condition, null, filter, true
);
}
}
private ApexObservatoryCastWithoutManaEffect(final ApexObservatoryCastWithoutManaEffect effect) {
super(effect);
this.chosenCardType = effect.chosenCardType;
this.playerId = effect.playerId;
this.used = effect.used;
this.spellCastCount = effect.spellCastCount;
this.filter = effect.filter;
this.alternativeCostSourceAbility = effect.alternativeCostSourceAbility;
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(playerId);
if (controller != null) {
MageObject spell = abilityToModify.getSourceObject(game);
if (spell != null && !game.isSimulation()) {
String message = "Cast " + spell.getIdName() + " without paying its mana cost?";
if (controller.chooseUse(Outcome.Benefit, message, source, game)) {
abilityToModify.getManaCostsToPay().clear();
used = true;
}
}
if (controller == null) {
return false;
}
alternativeCostSourceAbility.setSourceId(source.getSourceId());
controller.getAlternativeSourceCosts().add(alternativeCostSourceAbility);
return true;
}
@Override
public boolean isInactive(Ability source, Game game) {
return used || super.isInactive(source, game);
}
@Override
public boolean applies(Ability ability, Ability source, Game game) {
if (used) {
return false;
}
if (!ability.isControlledBy(playerId)) {
return false;
}
if (!(ability instanceof SpellAbility)) {
return false;
}
MageObject object = game.getObject(ability.getSourceId());
return object != null && object.getCardType(game).stream()
.anyMatch(cardType -> cardType.toString().equals(chosenCardType));
}
@Override
public ApexObservatoryCastWithoutManaEffect copy() {
return new ApexObservatoryCastWithoutManaEffect(this);

View file

@ -1,50 +0,0 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public final class FibrousEntangler extends CardImpl {
public FibrousEntangler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(4);
this.toughness = new MageInt(6);
// this card is the second face of double-faced card
this.nightCard = true;
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Fibrous Entangler must be blocked if able.
this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield)));
// Fibrous Entangler can block an additional creature each combat.
this.addAbility(new SimpleStaticAbility(new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1)));
}
private FibrousEntangler(final FibrousEntangler card) {
super(card);
}
@Override
public FibrousEntangler copy() {
return new FibrousEntangler(this);
}
}

View file

@ -1,70 +0,0 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.permanent.token.HumanWizardToken;
import java.util.UUID;
/**
* @author fireshoes
*/
public final class FinalIteration extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("Wizards");
static {
filter.add(SubType.WIZARD.getPredicate());
}
public FinalIteration(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.INSECT);
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// this card is the second face of double-faced card
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Wizards you control get +2/+1 and have flying.
Ability ability = new SimpleStaticAbility(new BoostControlledEffect(
2, 1, Duration.WhileOnBattlefield, filter, false
));
ability.addEffect(new GainAbilityControlledEffect(
FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter
).setText("and have flying"));
this.addAbility(ability);
// Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token.
this.addAbility(new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new HumanWizardToken()),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
));
}
private FinalIteration(final FinalIteration card) {
super(card);
}
@Override
public FinalIteration copy() {
return new FinalIteration(this);
}
}

View file

@ -1,158 +0,0 @@
package mage.cards.f;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.keyword.FirebendingAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.card.OwnerIdPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.util.CardUtil;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FireLordSozin extends CardImpl {
public FireLordSozin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.NOBLE);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
this.color.setBlack(true);
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility());
// Firebending 3
this.addAbility(new FirebendingAbility(3));
// Whenever Fire Lord Sozin deals combat damage to a player, you may pay {X}. When you do, put any number of target creature cards with total mana value X or less from that player's graveyard onto the battlefield under your control.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new FireLordSozinEffect()));
}
private FireLordSozin(final FireLordSozin card) {
super(card);
}
@Override
public FireLordSozin copy() {
return new FireLordSozin(this);
}
}
class FireLordSozinEffect extends OneShotEffect {
FireLordSozinEffect() {
super(Outcome.Benefit);
staticText = "you may pay {X}. When you do, put any number of target creature cards with " +
"total mana value X or less from that player's graveyard onto the battlefield under your control";
}
private FireLordSozinEffect(final FireLordSozinEffect effect) {
super(effect);
}
@Override
public FireLordSozinEffect copy() {
return new FireLordSozinEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
if (controller == null || !controller.chooseUse(Outcome.BoostCreature, "Pay {X}?", source, game)) {
return false;
}
int xValue = controller.announceX(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source, true);
ManaCosts cost = new ManaCostsImpl<>("{X}");
cost.add(new GenericManaCost(xValue));
if (!cost.pay(source, game, source, source.getControllerId(), false, null)) {
return false;
}
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), false);
ability.addTarget(new FireLordSozinTarget((UUID) getValue("damagedPlayer"), xValue));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}
class FireLordSozinTarget extends TargetCardInGraveyard {
private final int xValue;
private static final FilterCard makeFilter(UUID ownerId, int xValue) {
FilterCard filter = new FilterCreatureCard("creature cards with total mana value " + xValue + " or less from that player's graveyard");
filter.add(new OwnerIdPredicate(ownerId));
return filter;
}
FireLordSozinTarget(UUID ownerId, int xValue) {
super(0, Integer.MAX_VALUE, makeFilter(ownerId, xValue), false);
this.xValue = xValue;
}
private FireLordSozinTarget(final FireLordSozinTarget target) {
super(target);
this.xValue = target.xValue;
}
@Override
public FireLordSozinTarget copy() {
return new FireLordSozinTarget(this);
}
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
return super.canTarget(playerId, id, source, game)
&& CardUtil.checkCanTargetTotalValueLimit(this.getTargets(), id, MageObject::getManaValue, xValue, game);
}
@Override
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
return CardUtil.checkPossibleTargetsTotalValueLimit(
this.getTargets(),
super.possibleTargets(sourceControllerId, source, game),
MageObject::getManaValue, xValue, game
);
}
@Override
public String getMessage(Game game) {
// shows selected total
int selectedValue = this.getTargets().stream()
.map(game::getObject)
.filter(Objects::nonNull)
.mapToInt(MageObject::getManaValue)
.sum();
return super.getMessage(game) + " (selected total mana value " + selectedValue + ")";
}
}

View file

@ -1,44 +0,0 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FragmentOfKonda extends CardImpl {
public FragmentOfKonda(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
this.color.setWhite(true);
this.nightCard = true;
// Defender
this.addAbility(DefenderAbility.getInstance());
// When Fragment of Konda dies, draw a card.
this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1)));
}
private FragmentOfKonda(final FragmentOfKonda card) {
super(card);
}
@Override
public FragmentOfKonda copy() {
return new FragmentOfKonda(this);
}
}

View file

@ -1,22 +1,25 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.condition.common.IsMainPhaseCondition;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.*;
import mage.abilities.effects.common.AdditionalCombatPhaseEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.UntapAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AttackedThisTurnPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.turn.Turn;
import java.util.UUID;
/**
*
* @author Jmlundeen
*/
public final class FullThrottle extends CardImpl {
@ -24,16 +27,15 @@ public final class FullThrottle extends CardImpl {
public FullThrottle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
// After this main phase, there are two additional combat phases.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new AdditionalCombatPhaseEffect(2),
IsMainPhaseCondition.ANY,
new AdditionalCombatPhaseEffect(2), FullThrottleCondition.instance,
"After this main phase, there are two additional combat phases."
));
// At the beginning of each combat this turn, untap all creatures that attacked this turn.
DelayedTriggeredAbility ability = new FullThrottleTriggeredAbility();
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(ability).concatBy("<br>"));
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new FullThrottleTriggeredAbility())
.concatBy("<br>"));
}
private FullThrottle(final FullThrottle card) {
@ -46,14 +48,25 @@ public final class FullThrottle extends CardImpl {
}
}
enum FullThrottleCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
return game.getTurnPhaseType().isMain();
}
}
class FullThrottleTriggeredAbility extends DelayedTriggeredAbility {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that attacked this turn");
private static final FilterPermanent filter = new FilterCreaturePermanent("creatures that attacked this turn");
static {
filter.add(AttackedThisTurnPredicate.instance);
}
public FullThrottleTriggeredAbility() {
super(new UntapAllEffect(filter), Duration.EndOfTurn, false);
super(new UntapAllEffect(filter), Duration.EndOfTurn, false, false);
setTriggerPhrase("At the beginning of each combat this turn, ");
}
@ -73,7 +86,6 @@ class FullThrottleTriggeredAbility extends DelayedTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Turn turn = game.getState().getTurn();
return turn.getPhase().getType() == TurnPhase.COMBAT;
return true;
}
}
}

View file

@ -8,8 +8,6 @@ import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.effects.common.ReturnFromYourGraveyardToBattlefieldAllEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.CardType;
import mage.constants.SpellAbilityType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
@ -21,7 +19,7 @@ import java.util.UUID;
public final class FuneralRoomAwakeningHall extends RoomCard {
public FuneralRoomAwakeningHall(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}", "{6}{B}{B}", SpellAbilityType.SPLIT);
super(ownerId, setInfo, "{2}{B}", "{6}{B}{B}");
this.subtype.add(SubType.ROOM);
// Funeral Room: Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.

View file

@ -1,88 +0,0 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
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.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FurnaceBlessedConqueror extends CardImpl {
public FurnaceBlessedConqueror(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.color.setWhite(true);
this.color.setRed(true);
this.nightCard = true;
// Whenever Furnace-Blessed Conqueror attacks, create a tapped and attacking token that's a copy of it. Put a +1/+1 counter on that token for each +1/+1 counter on Furnace-Blessed Conqueror. Sacrifice that token at the beginning of the next end step.
this.addAbility(new AttacksTriggeredAbility(new FurnaceBlessedConquerorEffect()));
}
private FurnaceBlessedConqueror(final FurnaceBlessedConqueror card) {
super(card);
}
@Override
public FurnaceBlessedConqueror copy() {
return new FurnaceBlessedConqueror(this);
}
}
class FurnaceBlessedConquerorEffect extends OneShotEffect {
FurnaceBlessedConquerorEffect() {
super(Outcome.Benefit);
staticText = "create a tapped and attacking token that's a copy of it. " +
"Put a +1/+1 counter on that token for each +1/+1 counter on {this}. " +
"Sacrifice that token at the beginning of the next end step";
}
private FurnaceBlessedConquerorEffect(final FurnaceBlessedConquerorEffect effect) {
super(effect);
}
@Override
public FurnaceBlessedConquerorEffect copy() {
return new FurnaceBlessedConquerorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null) {
return false;
}
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(
null, null, false, 1, true, true
);
effect.setSavedPermanent(permanent);
effect.apply(game, source);
effect.sacrificeTokensCreatedAtNextEndStep(game, source);
int counters = permanent.getCounters(game).getCount(CounterType.P1P1);
if (counters < 1) {
return true;
}
for (Permanent token : effect.getAddedPermanents()) {
token.addCounters(CounterType.P1P1.createInstance(counters), source, game);
}
return true;
}
}

View file

@ -1,51 +0,0 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GalianBeast extends CardImpl {
public GalianBeast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.WEREWOLF);
this.subtype.add(SubType.BEAST);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
this.nightCard = true;
this.color.setBlack(true);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// When Galian Beast dies, return it to the battlefield tapped.
this.addAbility(new DiesSourceTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect(true)
.setText("return it to the battlefield tapped")));
}
private GalianBeast(final GalianBeast card) {
super(card);
}
@Override
public GalianBeast copy() {
return new GalianBeast(this);
}
}

View file

@ -0,0 +1,173 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.BecomesMonarchTargetEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.hint.common.MonarchHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GarlandRoyalKidnapper extends CardImpl {
private static final FilterControlledCreaturePermanent filter
= new FilterControlledCreaturePermanent("creatures you control but don't own");
static {
filter.add(TargetController.NOT_YOU.getOwnerPredicate());
}
public GarlandRoyalKidnapper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When Garland enters, target opponent becomes the monarch.
Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect());
ability.addTarget(new TargetOpponent());
this.addAbility(ability.addHint(MonarchHint.instance));
// Whenever an opponent becomes the monarch, gain control of target creature that player controls for as long as they're the monarch.
this.addAbility(new GarlandRoyalKidnapperTriggeredAbility());
// Creatures you control but don't own get +2/+2 and can't be sacrificed.
ability = new SimpleStaticAbility(new BoostAllEffect(
2, 2, Duration.WhileOnBattlefield, filter, false
));
ability.addEffect(new GarlandRoyalKidnapperSacrificeEffect());
this.addAbility(ability);
}
private GarlandRoyalKidnapper(final GarlandRoyalKidnapper card) {
super(card);
}
@Override
public GarlandRoyalKidnapper copy() {
return new GarlandRoyalKidnapper(this);
}
}
class GarlandRoyalKidnapperTriggeredAbility extends TriggeredAbilityImpl {
GarlandRoyalKidnapperTriggeredAbility() {
super(Zone.BATTLEFIELD, new GarlandRoyalKidnapperControlEffect());
this.addTarget(new TargetOpponent());
this.setTriggerPhrase("Whenever an opponent becomes the monarch, ");
}
private GarlandRoyalKidnapperTriggeredAbility(final GarlandRoyalKidnapperTriggeredAbility ability) {
super(ability);
}
@Override
public GarlandRoyalKidnapperTriggeredAbility copy() {
return new GarlandRoyalKidnapperTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.BECOMES_MONARCH;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Player player = game.getPlayer(event.getTargetId());
if (player == null || !game.getOpponents(getControllerId()).contains(player.getId())) {
return false;
}
FilterPermanent filter = new FilterCreaturePermanent("creature controlled by " + player.getName());
filter.add(new ControllerIdPredicate(player.getId()));
this.getTargets().clear();
this.addTarget(new TargetPermanent(filter));
this.getEffects().setValue("monarchId", player.getId());
return true;
}
}
class GarlandRoyalKidnapperControlEffect extends GainControlTargetEffect {
GarlandRoyalKidnapperControlEffect() {
super(Duration.Custom, true);
staticText = "gain control of target creature that player controls for as long as they're the monarch";
}
private GarlandRoyalKidnapperControlEffect(final GarlandRoyalKidnapperControlEffect effect) {
super(effect);
}
@Override
public GarlandRoyalKidnapperControlEffect copy() {
return new GarlandRoyalKidnapperControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null
&& Optional
.ofNullable((UUID) getValue("monarchId"))
.filter(uuid -> uuid.equals(game.getMonarchId()))
.isPresent()) {
return super.apply(game, source);
}
discard();
return false;
}
}
class GarlandRoyalKidnapperSacrificeEffect extends ContinuousEffectImpl {
GarlandRoyalKidnapperSacrificeEffect() {
super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit);
staticText = "and can't be sacrificed";
}
private GarlandRoyalKidnapperSacrificeEffect(final GarlandRoyalKidnapperSacrificeEffect effect) {
super(effect);
}
@Override
public GarlandRoyalKidnapperSacrificeEffect copy() {
return new GarlandRoyalKidnapperSacrificeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game
)) {
if (!permanent.isOwnedBy(source.getControllerId())) {
permanent.setCanBeSacrificed(true);
}
}
return true;
}
}

View file

@ -1,47 +0,0 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.ControlEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author BetaSteward
*/
public final class GhastlyHaunting extends CardImpl {
public GhastlyHaunting(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"");
this.subtype.add(SubType.AURA);
this.color.setBlue(true);
// this card is the second face of double-faced card
this.nightCard = true;
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.addAbility(new EnchantAbility(auraTarget));
// You control enchanted creature.
this.addAbility(new SimpleStaticAbility(new ControlEnchantedEffect()));
}
private GhastlyHaunting(final GhastlyHaunting card) {
super(card);
}
@Override
public GhastlyHaunting copy() {
return new GhastlyHaunting(this);
}
}

View file

@ -0,0 +1,91 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
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.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GhostlyKeybearer extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ROOM);
public GhostlyKeybearer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever this creature deals combat damage to a player, unlock a locked door of up to one target Room you control.
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new GhostlyKeybearerEffect());
ability.addTarget(new TargetPermanent(0, 1, filter));
this.addAbility(ability);
}
private GhostlyKeybearer(final GhostlyKeybearer card) {
super(card);
}
@Override
public GhostlyKeybearer copy() {
return new GhostlyKeybearer(this);
}
}
class GhostlyKeybearerEffect extends OneShotEffect {
GhostlyKeybearerEffect() {
super(Outcome.Benefit);
staticText = "unlock a locked door of up to one target Room you control";
}
private GhostlyKeybearerEffect(final GhostlyKeybearerEffect effect) {
super(effect);
}
@Override
public GhostlyKeybearerEffect copy() {
return new GhostlyKeybearerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null || !permanent.isLeftDoorUnlocked() && !permanent.isRightDoorUnlocked()) {
return false;
}
boolean unlockLeft;
if (!permanent.isLeftDoorUnlocked() && permanent.isRightDoorUnlocked()) {
unlockLeft = true;
} else if (permanent.isLeftDoorUnlocked() && !permanent.isRightDoorUnlocked()) {
unlockLeft = false;
} else {
unlockLeft = player.chooseUse(
Outcome.Neutral, "Unlock the left door or the right door?",
null, "Left", "Right", source, game
);
}
return permanent.unlockDoor(game, source, unlockLeft);
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.g;
import mage.abilities.Ability;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.TargetController;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GlassworksShatteredYard extends RoomCard {
public GlassworksShatteredYard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{R}", "{4}{R}");
// Glassworks
// When you unlock this door, this Room deals 4 damage to target creature an opponent controls.
Ability ability = new UnlockThisDoorTriggeredAbility(new DamageTargetEffect(4), false, true);
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.getLeftHalfCard().addAbility(ability);
// Shattered Yard
// At the beginning of your end step, this Room deals 1 damage to each opponent.
this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new DamagePlayersEffect(1, TargetController.OPPONENT)));
}
private GlassworksShatteredYard(final GlassworksShatteredYard card) {
super(card);
}
@Override
public GlassworksShatteredYard copy() {
return new GlassworksShatteredYard(this);
}
}

View file

@ -62,12 +62,9 @@ enum GoblinBlastRunnerCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
UUID player = source.getControllerId();
PermanentsSacrificedWatcher watcher = game.getState().getWatcher(PermanentsSacrificedWatcher.class);
if (watcher == null) {
return false;
}
return watcher.getThisTurnSacrificedPermanents(player) != null;
return watcher != null
&& !watcher.getThisTurnSacrificedPermanents(source.getControllerId()).isEmpty();
}
public static Hint getHint() {

View file

@ -20,7 +20,7 @@ import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
import java.util.UUID;
@ -61,7 +61,7 @@ public final class GornogTheRedReaper extends CardImpl {
Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility(
new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.COWARD).setText("target creature that player controls becomes a Coward"),
filterWarrior, SetTargetPointer.PLAYER);
ability.addTarget(new TargetPermanent());
ability.addTarget(new TargetCreaturePermanent());
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
this.addAbility(ability);

View file

@ -0,0 +1,42 @@
package mage.cards.g;
import mage.abilities.Ability;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.counters.CounterType;
import mage.game.permanent.token.GlimmerToken;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GrandEntrywayElegantRotunda extends RoomCard {
public GrandEntrywayElegantRotunda(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{1}{W}", "{2}{W}");
// Grand Entryway
// When you unlock this door, create a 1/1 white Glimmer enchantment creature token.
this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new CreateTokenEffect(new GlimmerToken()), false, true));
// Elegant Rotunda
// When you unlock this door, put a +1/+1 counter on each of up to two target creatures.
Ability ability = new UnlockThisDoorTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, false);
ability.addTarget(new TargetCreaturePermanent(0, 2));
this.getRightHalfCard().addAbility(ability);
}
private GrandEntrywayElegantRotunda(final GrandEntrywayElegantRotunda card) {
super(card);
}
@Override
public GrandEntrywayElegantRotunda copy() {
return new GrandEntrywayElegantRotunda(this);
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.g;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.common.MillThenPutInHandEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GreenhouseRicketyGazebo extends RoomCard {
public GreenhouseRicketyGazebo(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{G}", "{3}{G}");
// Greenhouse
// Lands you control have "{T}: Add one mana of any color."
ContinuousEffect effect = new GainAbilityControlledEffect(
new AnyColorManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS, false
);
effect.addDependedToType(DependencyType.BecomeNonbasicLand);
this.getLeftHalfCard().addAbility(new SimpleStaticAbility(effect));
// Rickety Gazebo
// When you unlock this door, mill four cards, then return up to two permanent cards from among them to your hand.
this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new MillThenPutInHandEffect(
4, StaticFilters.FILTER_CARD_PERMANENTS, null, true, 2
), false, false));
}
private GreenhouseRicketyGazebo(final GreenhouseRicketyGazebo card) {
super(card);
}
@Override
public GreenhouseRicketyGazebo copy() {
return new GreenhouseRicketyGazebo(this);
}
}

View file

@ -59,7 +59,7 @@ public final class GrimReapersSprint extends CardImpl {
"untap each creature you control"
), false
);
triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOUR, "If it's your main phase, there is an additional combat phase after this phase."));
triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOURS, "If it's your main phase, there is an additional combat phase after this phase."));
this.addAbility(triggeredAbility);
// Enchanted creature gets +2/+2 and has haste.
@ -110,4 +110,4 @@ class GrimReapersSprintCostModificationEffect extends CostModificationEffectImpl
public GrimReapersSprintCostModificationEffect copy() {
return new GrimReapersSprintCostModificationEffect(this);
}
}
}

View file

@ -1,163 +0,0 @@
package mage.cards.g;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.token.IzoniInsectToken;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTargets;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author Susucr
*/
public final class GristThePlagueSwarm extends CardImpl {
public GristThePlagueSwarm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GRIST);
this.setStartingLoyalty(3);
this.color.setBlack(true);
this.color.setGreen(true);
this.nightCard = true;
// +1: Create a 1/1 black and green Insect creature token, then mill two cards. Put a deathtouch counter on the token if a black card was milled this way.
this.addAbility(new LoyaltyAbility(new GristThePlagueSwarmPlus1Effect(), 1));
// -2: Destroy target artifact or enchantment.
Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -2);
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.addAbility(ability);
// -6: For each creature card in your graveyard, create a token that's a copy of it, except it's a 1/1 black and green Insect.
this.addAbility(new LoyaltyAbility(new GristThePlagueSwarmMinus6Effect(), -6));
}
private GristThePlagueSwarm(final GristThePlagueSwarm card) {
super(card);
}
@Override
public GristThePlagueSwarm copy() {
return new GristThePlagueSwarm(this);
}
}
class GristThePlagueSwarmPlus1Effect extends OneShotEffect {
GristThePlagueSwarmPlus1Effect() {
super(Outcome.PutCreatureInPlay);
staticText = "Create a 1/1 black and green Insect creature token, then mill two cards. "
+ "Put a deathtouch counter on the token if a black card was milled this way.";
}
private GristThePlagueSwarmPlus1Effect(final GristThePlagueSwarmPlus1Effect effect) {
super(effect);
}
@Override
public GristThePlagueSwarmPlus1Effect copy() {
return new GristThePlagueSwarmPlus1Effect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
// Create a 1/1 black and green Insect creature token
CreateTokenEffect effect = new CreateTokenEffect(new IzoniInsectToken());
effect.apply(game, source);
// Then mill two cards
Cards cards = controller.millCards(2, source, game);
// Put a deathtouch counter on the token if a black card was milled this way.
if (cards.getCards(game).stream().anyMatch(card -> card.getColor(game).isBlack())) {
List<Permanent> tokens = effect
.getLastAddedTokenIds()
.stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (!tokens.isEmpty()) {
Effect addEffect = new AddCountersTargetEffect(CounterType.DEATHTOUCH.createInstance());
addEffect.setTargetPointer(new FixedTargets(tokens, game));
addEffect.apply(game, source);
}
}
return true;
}
}
class GristThePlagueSwarmMinus6Effect extends OneShotEffect {
GristThePlagueSwarmMinus6Effect() {
super(Outcome.PutCreatureInPlay);
staticText = "For each creature card in your graveyard, create a token that's a copy of it, "
+ "except it's a 1/1 black and green Insect.";
}
private GristThePlagueSwarmMinus6Effect(final GristThePlagueSwarmMinus6Effect effect) {
super(effect);
}
@Override
public GristThePlagueSwarmMinus6Effect copy() {
return new GristThePlagueSwarmMinus6Effect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Set<Card> cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
if (cards.isEmpty()) {
return false;
}
for (Card card : cards) {
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(
null, null, false, 1, false,
false, null, 1, 1, false
);
effect.setSavedPermanent(new PermanentCard(card, controller.getId(), game));
effect.setOnlyColor(new ObjectColor("BG"));
effect.setOnlySubType(SubType.INSECT);
effect.apply(game, source);
}
return true;
}
}

View file

@ -1,46 +1,73 @@
package mage.cards.g;
import mage.MageInt;
import mage.constants.Pronoun;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.ExileAndReturnSourceEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.*;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.Card;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.token.IzoniInsectToken;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTargets;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author Susucr
*/
public final class GristVoraciousLarva extends CardImpl {
public final class GristVoraciousLarva extends TransformingDoubleFacedCard {
public GristVoraciousLarva(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.INSECT}, "{G}",
"Grist, the Plague Swarm",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.GRIST}, "BG"
);
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.INSECT);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
this.secondSideCardClazz = GristThePlagueSwarm.class;
// Grist, Voracious Larva
this.getLeftHalfCard().setPT(1, 2);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
this.getLeftHalfCard().addAbility(DeathtouchAbility.getInstance());
// Whenever Grist, Voracious Larva or another creature you control enters, if it entered from your graveyard or was cast from your graveyard, you may pay {G}. If you do, exile Grist, then return it to the battlefield transformed under its owner's control.
this.addAbility(new TransformAbility());
this.addAbility(new GristVoraciousLarvaTriggeredAbility());
this.getLeftHalfCard().addAbility(new GristVoraciousLarvaTriggeredAbility());
// Grist, the Plague Swarm
this.getRightHalfCard().setStartingLoyalty(3);
// +1: Create a 1/1 black and green Insect creature token, then mill two cards. Put a deathtouch counter on the token if a black card was milled this way.
this.getRightHalfCard().addAbility(new LoyaltyAbility(new GristThePlagueSwarmPlus1Effect(), 1));
// -2: Destroy target artifact or enchantment.
Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -2);
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.getRightHalfCard().addAbility(ability);
// -6: For each creature card in your graveyard, create a token that's a copy of it, except it's a 1/1 black and green Insect.
this.getRightHalfCard().addAbility(new LoyaltyAbility(new GristThePlagueSwarmMinus6Effect(), -6));
}
private GristVoraciousLarva(final GristVoraciousLarva card) {
@ -100,3 +127,93 @@ class GristVoraciousLarvaTriggeredAbility extends EntersBattlefieldThisOrAnother
return fromGraveyard && super.checkTrigger(event, game);
}
}
class GristThePlagueSwarmPlus1Effect extends OneShotEffect {
GristThePlagueSwarmPlus1Effect() {
super(Outcome.PutCreatureInPlay);
staticText = "Create a 1/1 black and green Insect creature token, then mill two cards. "
+ "Put a deathtouch counter on the token if a black card was milled this way.";
}
private GristThePlagueSwarmPlus1Effect(final GristThePlagueSwarmPlus1Effect effect) {
super(effect);
}
@Override
public GristThePlagueSwarmPlus1Effect copy() {
return new GristThePlagueSwarmPlus1Effect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
// Create a 1/1 black and green Insect creature token
CreateTokenEffect effect = new CreateTokenEffect(new IzoniInsectToken());
effect.apply(game, source);
// Then mill two cards
Cards cards = controller.millCards(2, source, game);
// Put a deathtouch counter on the token if a black card was milled this way.
if (cards.getCards(game).stream().anyMatch(card -> card.getColor(game).isBlack())) {
List<Permanent> tokens = effect
.getLastAddedTokenIds()
.stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (!tokens.isEmpty()) {
Effect addEffect = new AddCountersTargetEffect(CounterType.DEATHTOUCH.createInstance());
addEffect.setTargetPointer(new FixedTargets(tokens, game));
addEffect.apply(game, source);
}
}
return true;
}
}
class GristThePlagueSwarmMinus6Effect extends OneShotEffect {
GristThePlagueSwarmMinus6Effect() {
super(Outcome.PutCreatureInPlay);
staticText = "For each creature card in your graveyard, create a token that's a copy of it, "
+ "except it's a 1/1 black and green Insect.";
}
private GristThePlagueSwarmMinus6Effect(final GristThePlagueSwarmMinus6Effect effect) {
super(effect);
}
@Override
public GristThePlagueSwarmMinus6Effect copy() {
return new GristThePlagueSwarmMinus6Effect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Set<Card> cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
if (cards.isEmpty()) {
return false;
}
for (Card card : cards) {
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(
null, null, false, 1, false,
false, null, 1, 1, false
);
effect.setSavedPermanent(new PermanentCard(card, controller.getId(), game));
effect.setOnlyColor(new ObjectColor("BG"));
effect.setOnlySubType(SubType.INSECT);
effect.apply(game, source);
}
return true;
}
}

View file

@ -1,23 +1,17 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import java.util.UUID;
@ -26,16 +20,6 @@ import java.util.UUID;
*/
public final class HauntOfTheDeadMarshes extends CardImpl {
private static final FilterPermanent filter
= new FilterControlledCreaturePermanent("you control a legendary creature");
static {
filter.add(SuperType.LEGENDARY.getPredicate());
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
private static final Hint hint = new ConditionHint(condition, "You control a legendary creature");
public HauntOfTheDeadMarshes(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
@ -50,8 +34,8 @@ public final class HauntOfTheDeadMarshes extends CardImpl {
// {2}{B}: Return Haunt of the Dead Marshes from your graveyard to the battlefield tapped. Activate only if you control a legendary creature.
this.addAbility(new ActivateIfConditionActivatedAbility(
Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(true, false),
new ManaCostsImpl<>("{2}{B}"), condition
).addHint(hint));
new ManaCostsImpl<>("{2}{B}"), YouControlALegendaryCreatureCondition.instance
).addHint(YouControlALegendaryCreatureCondition.getHint()));
}
private HauntOfTheDeadMarshes(final HauntOfTheDeadMarshes card) {

View file

@ -0,0 +1,92 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.ProliferateEffect;
import mage.abilities.effects.keyword.BlightControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HighPerfectMorcant extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.ELF, "Elf");
private static final FilterControlledPermanent filter2
= new FilterControlledPermanent(SubType.ELF, "untapped Elves you control");
static {
filter2.add(TappedPredicate.UNTAPPED);
}
public HighPerfectMorcant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.NOBLE);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Whenever High Perfect Morcant or another Elf you control enters, each opponent blights 1.
this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility(
new HighPerfectMorcantEffect(), filter, false, true
));
// Tap three untapped Elves you control: Proliferate. Activate only as a sorcery.
this.addAbility(new ActivateAsSorceryActivatedAbility(
new ProliferateEffect(), new TapTargetCost(3, filter2)
));
}
private HighPerfectMorcant(final HighPerfectMorcant card) {
super(card);
}
@Override
public HighPerfectMorcant copy() {
return new HighPerfectMorcant(this);
}
}
class HighPerfectMorcantEffect extends OneShotEffect {
HighPerfectMorcantEffect() {
super(Outcome.Benefit);
staticText = "each opponent blights 1. <i>(They each put a -1/-1 counter on a creature they control.)</i>";
}
private HighPerfectMorcantEffect(final HighPerfectMorcantEffect effect) {
super(effect);
}
@Override
public HighPerfectMorcantEffect copy() {
return new HighPerfectMorcantEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
BlightControllerEffect.doBlight(opponent, 1, game, source);
}
return true;
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesWithLessPowerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.permanent.token.EldraziHorrorToken;
/**
*
* @author LevelX2
*/
public final class HowlingChorus extends CardImpl {
public HowlingChorus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
this.subtype.add(SubType.ELDRAZI);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// this card is the second face of double-faced card
this.nightCard = true;
// Creatures with power less than Howling Chorus's power can't block it.
this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesWithLessPowerEffect()));
// Whenever Howling Chorus deals combat damage to a player, create a 3/2 colorless Eldrazi Horror creature token.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenEffect(new EldraziHorrorToken()), false));
}
private HowlingChorus(final HowlingChorus card) {
super(card);
}
@Override
public HowlingChorus copy() {
return new HowlingChorus(this);
}
}

View file

@ -1,40 +0,0 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author nantuko
*/
public final class HowlpackOfEstwald extends CardImpl {
public HowlpackOfEstwald(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.color.setGreen(true);
// this card is the second face of double-faced card
this.nightCard = true;
this.power = new MageInt(4);
this.toughness = new MageInt(6);
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack of Estwald.
this.addAbility(new WerewolfBackTriggeredAbility());
}
private HowlpackOfEstwald(final HowlpackOfEstwald card) {
super(card);
}
@Override
public HowlpackOfEstwald copy() {
return new HowlpackOfEstwald(this);
}
}

View file

@ -0,0 +1,140 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedBatchBySourceEvent;
import mage.game.events.GameEvent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HumanTorch extends CardImpl {
public HumanTorch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// At the beginning of combat on your turn, if you've cast a noncreature spell this turn, Human Torch gains flying, double strike, and haste until end of turn.
Ability ability = new BeginningOfCombatTriggeredAbility(
new GainAbilitySourceEffect(
FlyingAbility.getInstance(), Duration.EndOfTurn
).setText("{this} gains flying")
).withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance);
ability.addEffect(new GainAbilitySourceEffect(
DoubleStrikeAbility.getInstance(), Duration.EndOfTurn
).setText(", double strike"));
ability.addEffect(new GainAbilitySourceEffect(
HasteAbility.getInstance(), Duration.EndOfTurn
).setText(", and haste until end of turn."));
this.addAbility(ability.addHint(CastNoncreatureSpellThisTurnCondition.getHint()));
// Whenever Human Torch attacks, you may pay {R}{G}{W}{U}. If you do, until end of turn, whenever he deals combat damage to an opponent, he deals that much damage to each other opponent.
this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
new CreateDelayedTriggeredAbilityEffect(new HumanTorchTriggeredAbility())
.setText("until end of turn, whenever he deals combat damage to an opponent, " +
"he deals that much damage to each other opponent"),
new ManaCostsImpl<>("{R}{G}{W}{U}")
)));
}
private HumanTorch(final HumanTorch card) {
super(card);
}
@Override
public HumanTorch copy() {
return new HumanTorch(this);
}
}
class HumanTorchTriggeredAbility extends DelayedTriggeredAbility {
HumanTorchTriggeredAbility() {
super(new HumanTorchEffect(), Duration.EndOfTurn, false, false);
setTriggerPhrase("Whenever {this} deals combat damage to an opponent, ");
}
private HumanTorchTriggeredAbility(final HumanTorchTriggeredAbility ability) {
super(ability);
}
@Override
public HumanTorchTriggeredAbility copy() {
return new HumanTorchTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_BATCH_BY_SOURCE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!event.getSourceId().equals(getSourceId())
|| !((DamagedBatchBySourceEvent) event).isCombatDamage()
|| !game.getOpponents(getControllerId()).contains(event.getTargetId())) {
return false;
}
this.getEffects().setValue("playerId", event.getTargetId());
this.getEffects().setValue("damage", event.getAmount());
return true;
}
}
class HumanTorchEffect extends OneShotEffect {
HumanTorchEffect() {
super(Outcome.Benefit);
staticText = "he deals that much damage to each other opponent";
}
private HumanTorchEffect(final HumanTorchEffect effect) {
super(effect);
}
@Override
public HumanTorchEffect copy() {
return new HumanTorchEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID playerId = (UUID) getValue("playerId");
int damage = (Integer) getValue("damage");
if (damage < 1) {
return false;
}
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
if (!opponentId.equals(playerId)) {
Optional.ofNullable(opponentId)
.map(game::getPlayer)
.ifPresent(player -> player.damage(damage, source, game));
}
}
return true;
}
}

View file

@ -1,89 +0,0 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Controllable;
import mage.game.Game;
import mage.target.TargetPermanent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HydaelynTheMothercrystal extends CardImpl {
public HydaelynTheMothercrystal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.nightCard = true;
this.color.setWhite(true);
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
// Blessing of Light -- At the beginning of combat on your turn, put a +1/+1 counter on another target creature you control. Until your next turn, it gains indestructible. If that creature is legendary, draw a card.
Ability ability = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addEffect(new GainAbilityTargetEffect(
IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn
).setText("Until your next turn, it gains indestructible"));
ability.addEffect(new HydaelynTheMothercrystalEffect());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL));
this.addAbility(ability.withFlavorWord("Blessing of Light"));
}
private HydaelynTheMothercrystal(final HydaelynTheMothercrystal card) {
super(card);
}
@Override
public HydaelynTheMothercrystal copy() {
return new HydaelynTheMothercrystal(this);
}
}
class HydaelynTheMothercrystalEffect extends OneShotEffect {
HydaelynTheMothercrystalEffect() {
super(Outcome.Benefit);
staticText = "If that creature is legendary, draw a card";
}
private HydaelynTheMothercrystalEffect(final HydaelynTheMothercrystalEffect effect) {
super(effect);
}
@Override
public HydaelynTheMothercrystalEffect copy() {
return new HydaelynTheMothercrystalEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return Optional.ofNullable(getTargetPointer().getFirst(game, source))
.map(game::getPermanent)
.filter(permanent -> permanent.isLegendary(game))
.isPresent()
&& Optional
.ofNullable(source)
.map(Controllable::getControllerId)
.map(game::getPlayer)
.filter(player -> player.drawCards(1, source, game) > 0)
.isPresent();
}
}

View file

@ -1,48 +0,0 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksEachCombatStaticAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public final class IncitedRabble extends CardImpl {
public IncitedRabble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
this.subtype.add(SubType.HUMAN);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.color.setRed(true);
// this card is the second face of double-faced card
this.nightCard = true;
// Incited Rabble attacks each combat if able.
this.addAbility(new AttacksEachCombatStaticAbility());
// {2}: Incited Rabble gets +1/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{2}")));
}
private IncitedRabble(final IncitedRabble card) {
super(card);
}
@Override
public IncitedRabble copy() {
return new IncitedRabble(this);
}
}

View file

@ -0,0 +1,63 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.game.permanent.token.WallColorlessReachToken;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class InvisibleWoman extends CardImpl {
public InvisibleWoman(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// At the beginning of combat on your turn, if you've cast a noncreature spell this turn, create a 0/3 colorless Wall creature token with defender and reach.
this.addAbility(new BeginningOfCombatTriggeredAbility(new CreateTokenEffect(new WallColorlessReachToken()))
.withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance)
.addHint(CastNoncreatureSpellThisTurnCondition.getHint()));
// Whenever you attack, you may pay {R}{G}{W}{U}. When you do, target creature gets +1/+0 until end of turn for each creature you control and can't be blocked this turn.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new BoostTargetEffect(CreaturesYouControlCount.SINGULAR, StaticValue.get(0)), false
);
ability.addEffect(new CantBeBlockedTargetEffect().setText("and can't be blocked this turn"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new DoWhenCostPaid(
ability, new ManaCostsImpl<>("{R}{G}{W}{U}"), "Pay {R}{G}{W}{U}?"
), 1));
}
private InvisibleWoman(final InvisibleWoman card) {
super(card);
}
@Override
public InvisibleWoman copy() {
return new InvisibleWoman(this);
}
}

View file

@ -1,43 +0,0 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author nantuko
*/
public final class Ironfang extends CardImpl {
public Ironfang(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.color.setRed(true);
// this card is the second face of double-faced card
this.nightCard = true;
this.power = new MageInt(3);
this.toughness = new MageInt(1);
this.addAbility(FirstStrikeAbility.getInstance());
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ironfang.
this.addAbility(new WerewolfBackTriggeredAbility());
}
private Ironfang(final Ironfang card) {
super(card);
}
@Override
public Ironfang copy() {
return new Ironfang(this);
}
}

View file

@ -8,6 +8,7 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.keyword.CraftAbility;
import mage.cards.Card;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
@ -66,9 +67,15 @@ enum JadeheartAttendantValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Card sourceCard = game.getCard(sourceAbility.getSourceId());
if (sourceCard == null) {
return 0;
}
ExileZone exileZone = game
.getExile()
.getExileZone(CardUtil.getExileZoneId(game, sourceAbility, -2));
.getExileZone(CardUtil.getExileZoneId(game,
sourceCard.getMainCard().getMainCard().getId(),
sourceCard.getMainCard().getZoneChangeCounter(game) - 1));
return exileZone != null
? exileZone
.getCards(game)

View file

@ -34,8 +34,7 @@ public final class JaredCarthalionTrueHeir extends CardImpl {
this.toughness = new MageInt(3);
// When Jared Carthalion, True Heir enters the battlefield, target opponent becomes the monarch. You can't become the monarch this turn.
Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect()
.setText("target opponent becomes the monarch"));
Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect());
ability.addEffect(new JaredCarthalionTrueHeirMonarchEffect());
ability.addTarget(new TargetOpponent());
ability.addHint(MonarchHint.instance);

View file

@ -1,107 +0,0 @@
package mage.cards.j;
import java.util.Objects;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.EscapeAbility;
import mage.abilities.mana.DynamicManaAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author jimga150
*/
public final class JurassicPark extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent("Dinosaur you control");
static {
filter.add(SubType.DINOSAUR.getPredicate());
}
private static final Hint hint = new ValueHint(
"Number of Dinosaurs you control", new PermanentsOnBattlefieldCount(filter)
);
public JurassicPark(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
this.nightCard = true;
// (Transforms from Welcome to ....)
// Each Dinosaur card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard.
// Based on Underworld Breach
this.addAbility(new SimpleStaticAbility(new JurassicParkEffect()));
// {T}: Add {G} for each Dinosaur you control.
// Based on Gaea's Cradle
DynamicManaAbility ability = new DynamicManaAbility(
Mana.GreenMana(1),
new PermanentsOnBattlefieldCount(filter)
);
this.addAbility(ability.addHint(hint));
}
private JurassicPark(final JurassicPark card) {
super(card);
}
@Override
public JurassicPark copy() {
return new JurassicPark(this);
}
}
class JurassicParkEffect extends ContinuousEffectImpl {
JurassicParkEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
staticText = "Each Dinosaur card in your graveyard has escape. " +
"The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard.";
}
private JurassicParkEffect(final JurassicParkEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
controller
.getGraveyard()
.getCards(game)
.stream()
.filter(Objects::nonNull)
.filter(card -> !card.getManaCost().getText().isEmpty()) // card must have a mana cost
.filter(card -> card.hasSubtype(SubType.DINOSAUR, game))
.forEach(card -> {
Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3);
ability.setSourceId(card.getId());
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
});
return true;
}
@Override
public JurassicParkEffect copy() {
return new JurassicParkEffect(this);
}
}

View file

@ -1,137 +0,0 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.token.SpiritToken;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author weirddan455
*/
public final class KirinTouchedOrochi extends CardImpl {
private static final FilterCard filter = new FilterCard("noncreature card from a graveyard");
static {
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
}
public KirinTouchedOrochi(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.SNAKE);
this.subtype.add(SubType.MONK);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
this.color.setGreen(true);
this.nightCard = true;
// Whenever Kirin-Touched Orochi attacks, choose one
// Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token.
Ability ability = new AttacksTriggeredAbility(new KirinTouchedOrochiTokenEffect());
ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD));
// Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control.
Mode mode = new Mode(new KirinTouchedOrochiCounterEffect());
mode.addTarget(new TargetCardInGraveyard(filter));
ability.addMode(mode);
this.addAbility(ability);
}
private KirinTouchedOrochi(final KirinTouchedOrochi card) {
super(card);
}
@Override
public KirinTouchedOrochi copy() {
return new KirinTouchedOrochi(this);
}
}
class KirinTouchedOrochiTokenEffect extends OneShotEffect {
KirinTouchedOrochiTokenEffect() {
super(Outcome.Exile);
this.staticText = "Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token";
}
private KirinTouchedOrochiTokenEffect(final KirinTouchedOrochiTokenEffect effect) {
super(effect);
}
@Override
public KirinTouchedOrochiTokenEffect copy() {
return new KirinTouchedOrochiTokenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
UUID targetId = source.getFirstTarget();
Card card = game.getCard(targetId);
if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
return false;
}
if (!controller.moveCards(card, Zone.EXILED, source, game)) {
return false;
}
ReflexiveTriggeredAbility reflexiveTokenAbility = new ReflexiveTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false);
game.fireReflexiveTriggeredAbility(reflexiveTokenAbility, source);
return true;
}
}
class KirinTouchedOrochiCounterEffect extends OneShotEffect {
KirinTouchedOrochiCounterEffect() {
super(Outcome.Exile);
this.staticText = "Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control";
}
private KirinTouchedOrochiCounterEffect(final KirinTouchedOrochiCounterEffect effect) {
super(effect);
}
@Override
public KirinTouchedOrochiCounterEffect copy() {
return new KirinTouchedOrochiCounterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
UUID targetId = source.getFirstTarget();
Card card = game.getCard(targetId);
if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
return false;
}
if (!controller.moveCards(card, Zone.EXILED, source, game)) {
return false;
}
ReflexiveTriggeredAbility reflexiveCounterAbility = new ReflexiveTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false);
reflexiveCounterAbility.addTarget(new TargetControlledCreaturePermanent());
game.fireReflexiveTriggeredAbility(reflexiveCounterAbility, source);
return true;
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.TargetStackObject;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KirolAttentiveFirstYear extends CardImpl {
public KirolAttentiveFirstYear(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R/W}{R/W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Tap two untapped creatures you control: Copy target triggered ability you control. You may choose new targets for the copy. Activate only once each turn.
Ability ability = new LimitedTimesPerTurnActivatedAbility(
new CopyTargetStackObjectEffect(), new TapTargetCost(2, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES)
);
ability.addTarget(new TargetStackObject(StaticFilters.FILTER_CONTROLLED_TRIGGERED_ABILITY));
this.addAbility(ability);
}
private KirolAttentiveFirstYear(final KirolAttentiveFirstYear card) {
super(card);
}
@Override
public KirolAttentiveFirstYear copy() {
return new KirolAttentiveFirstYear(this);
}
}

View file

@ -1,47 +0,0 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID;
/**
* @author Loki
*/
public final class KrallenhordeKiller extends CardImpl {
public KrallenhordeKiller(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.color.setGreen(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.nightCard = true;
// {3}{G}: Krallenhorde Killer gets +4/+4 until end of turn. Activate this ability only once each turn.
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(4, 4, Duration.EndOfTurn), new ManaCostsImpl<>("{3}{G}")));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Killer.
this.addAbility(new WerewolfBackTriggeredAbility());
}
private KrallenhordeKiller(final KrallenhordeKiller card) {
super(card);
}
@Override
public KrallenhordeKiller copy() {
return new KrallenhordeKiller(this);
}
}

View file

@ -1,98 +0,0 @@
package mage.cards.l;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.common.ActivateAbilityTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.CopyStackObjectEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterStackObject;
import mage.filter.common.FilterActivatedOrTriggeredAbility;
import mage.filter.predicate.other.NotManaAbilityPredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class LocusOfEnlightenment extends CardImpl {
private static final FilterStackObject filter = new FilterActivatedOrTriggeredAbility("an ability that isn't a mana ability");
static {
filter.add(NotManaAbilityPredicate.instance);
}
public LocusOfEnlightenment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.supertype.add(SuperType.LEGENDARY);
this.nightCard = true;
this.color.setBlue(true);
// Locus of Enlightenment has each activated ability of the exiled cards used to craft it. You may activate each of those abilities only once each turn.
this.addAbility(new SimpleStaticAbility(new LocusOfEnlightenmentEffect()));
// Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy.
this.addAbility(new ActivateAbilityTriggeredAbility(new CopyStackObjectEffect("it"), filter, SetTargetPointer.SPELL));
}
private LocusOfEnlightenment(final LocusOfEnlightenment card) {
super(card);
}
@Override
public LocusOfEnlightenment copy() {
return new LocusOfEnlightenment(this);
}
}
class LocusOfEnlightenmentEffect extends ContinuousEffectImpl {
LocusOfEnlightenmentEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.Benefit);
staticText = "{this} has each activated ability of the exiled cards " +
"used to craft it. You may activate each of those abilities only once each turn";
}
private LocusOfEnlightenmentEffect(final LocusOfEnlightenmentEffect effect) {
super(effect);
}
@Override
public LocusOfEnlightenmentEffect copy() {
return new LocusOfEnlightenmentEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null) {
return false;
}
ExileZone exileZone = game
.getExile()
.getExileZone(CardUtil.getExileZoneId(
game, permanent.getId(), permanent.getZoneChangeCounter(game) - 2
));
if (exileZone == null) {
return false;
}
for (Card card : exileZone.getCards(game)) {
for (Ability ability : card.getAbilities(game)) {
if (ability.isActivatedAbility()) {
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
copyAbility.setMaxActivationsPerTurn(1);
permanent.addAbility(copyAbility, source.getSourceId(), game, true);
}
}
}
return true;
}
}

View file

@ -1,42 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MagickedCard extends CardImpl {
public MagickedCard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.nightCard = true;
this.color.setBlue(true);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Crew 1
this.addAbility(new CrewAbility(1));
}
private MagickedCard(final MagickedCard card) {
super(card);
}
@Override
public MagickedCard copy() {
return new MagickedCard(this);
}
}

View file

@ -1,88 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.ExileZone;
import mage.game.Game;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MastercraftRaptor extends CardImpl {
public MastercraftRaptor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "");
this.subtype.add(SubType.DINOSAUR);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
this.nightCard = true;
this.color.setRed(true);
// Mastercraft Raptor's power is equal to the total power of the exiled cards used to craft it.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new SetBasePowerSourceEffect(MastercraftRaptorValue.instance)
.setText("{this}'s power is equal to the total power of the exiled cards used to craft it")
));
}
private MastercraftRaptor(final MastercraftRaptor card) {
super(card);
}
@Override
public MastercraftRaptor copy() {
return new MastercraftRaptor(this);
}
}
enum MastercraftRaptorValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
ExileZone exileZone = game
.getExile()
.getExileZone(CardUtil.getExileZoneId(
game, sourceAbility.getSourceId(),
game.getState().getZoneChangeCounter(sourceAbility.getSourceId()) - 2
));
if (exileZone == null) {
return 0;
}
return exileZone
.getCards(game)
.stream()
.map(MageObject::getPower)
.mapToInt(MageInt::getValue)
.sum();
}
@Override
public MastercraftRaptorValue copy() {
return this;
}
@Override
public String getMessage() {
return "";
}
@Override
public String toString() {
return "1";
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MeatLockerDrownedDiner extends RoomCard {
public MeatLockerDrownedDiner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{U}", "{3}{U}{U}");
// Meat Locker
// When you unlock this door, tap up to one target creature and put two stun counters on it.
Ability ability = new UnlockThisDoorTriggeredAbility(new TapTargetEffect(), false, true);
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance(2))
.setText("and put two stun counters on it"));
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.getLeftHalfCard().addAbility(ability);
// Drowned Diner
// When you unlock this door, draw three cards, then discard a card.
this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(
new DrawDiscardControllerEffect(3, 1), false, false
));
}
private MeatLockerDrownedDiner(final MeatLockerDrownedDiner card) {
super(card);
}
@Override
public MeatLockerDrownedDiner copy() {
return new MeatLockerDrownedDiner(this);
}
}

View file

@ -4,7 +4,7 @@ import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.YouControlPermanentCondition;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@ -16,8 +16,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.WatcherScope;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.util.CardUtil;
@ -32,21 +30,14 @@ import java.util.UUID;
*/
public final class MinasTirith extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature");
static {
filter.add(SuperType.LEGENDARY.getPredicate());
}
private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter);
public MinasTirith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
// Minas Tirith enters the battlefield tapped unless you control a legendary creature.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint()));
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance)
.addHint(YouControlALegendaryCreatureCondition.getHint()));
// {T}: Add {W}.
this.addAbility(new WhiteManaAbility());

View file

@ -3,7 +3,7 @@ package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.YouControlPermanentCondition;
import mage.abilities.condition.common.YouControlALegendaryCreatureCondition;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -13,8 +13,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.permanent.token.TreasureToken;
import mage.target.common.TargetCardInYourGraveyard;
@ -25,21 +23,14 @@ import java.util.UUID;
*/
public final class MinesOfMoria extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature");
static {
filter.add(SuperType.LEGENDARY.getPredicate());
}
private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter);
public MinesOfMoria(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.supertype.add(SuperType.LEGENDARY);
// Mines of Moria enters the battlefield tapped unless you control a legendary creature.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint()));
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance)
.addHint(YouControlALegendaryCreatureCondition.getHint()));
// {T}: Add {R}.
this.addAbility(new RedManaAbility());

View file

@ -0,0 +1,89 @@
package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MirrorRoomFracturedRealm extends RoomCard {
public MirrorRoomFracturedRealm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{U}", "{5}{U}{U}");
// Mirror Room
// When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.
Ability ability = new UnlockThisDoorTriggeredAbility(
new CreateTokenCopyTargetEffect()
.withAdditionalSubType(SubType.REFLECTION)
.setText("create a token that's a copy of target creature you control, " +
"except it's a Reflection in addition to its other creature types"),
false, true
);
ability.addTarget(new TargetControlledCreaturePermanent());
this.getLeftHalfCard().addAbility(ability);
// Fractured Realm
// If a triggered ability of a permanent you control triggers, that ability triggers an additional time.
this.getRightHalfCard().addAbility(new SimpleStaticAbility(new FracturedRealmEffect()));
}
private MirrorRoomFracturedRealm(final MirrorRoomFracturedRealm card) {
super(card);
}
@Override
public MirrorRoomFracturedRealm copy() {
return new MirrorRoomFracturedRealm(this);
}
}
class FracturedRealmEffect extends ReplacementEffectImpl {
FracturedRealmEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "if a triggered ability of a permanent you control triggers, " +
"that ability triggers an additional time";
}
private FracturedRealmEffect(final FracturedRealmEffect effect) {
super(effect);
}
@Override
public FracturedRealmEffect copy() {
return new FracturedRealmEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
return permanent != null && permanent.isControlledBy(source.getControllerId());
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(CardUtil.overflowInc(event.getAmount(), 1));
return false;
}
}

View file

@ -0,0 +1,67 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.TargetStackObject;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MisterFantastic extends CardImpl {
public MisterFantastic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCIENTIST);
this.subtype.add(SubType.HERO);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Reach
this.addAbility(ReachAbility.getInstance());
// At the beginning of combat on your turn, if you've cast a noncreature spell this turn, draw a card.
this.addAbility(new BeginningOfCombatTriggeredAbility(new DrawCardSourceControllerEffect(1))
.withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance)
.addHint(CastNoncreatureSpellThisTurnCondition.getHint()));
// {R}{G}{W}{U}, {T}: Copy target triggered ability you control twice. You may choose new targets for the copies.
Ability ability = new SimpleActivatedAbility(new CopyTargetStackObjectEffect()
.setText("copy target triggered ability you control twice"), new ManaCostsImpl<>("{R}{G}{W}{U}"));
ability.addCost(new TapSourceCost());
ability.addEffect(new CopyTargetStackObjectEffect().setText("You may choose new targets for the copies."));
ability.addTarget(new TargetStackObject(StaticFilters.FILTER_CONTROLLED_TRIGGERED_ABILITY));
this.addAbility(ability);
}
private MisterFantastic(final MisterFantastic card) {
super(card);
}
@Override
public MisterFantastic copy() {
return new MisterFantastic(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.m;
import mage.abilities.common.UnlockThisDoorTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.effects.keyword.ManifestDreadEffect;
import mage.cards.CardSetInfo;
import mage.cards.RoomCard;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MolderingGymWeightRoom extends RoomCard {
public MolderingGymWeightRoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, "{2}{G}", "{5}{G}");
// Moldering Gym
// When you unlock this door, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.
this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(
new SearchLibraryPutInPlayEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
), false, true
));
// Weight Room
// When you unlock this door, manifest dread, then put three +1/+1 counters on that creature.
this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(
new ManifestDreadEffect(CounterType.P1P1.createInstance(3)), false, false
));
}
private MolderingGymWeightRoom(final MolderingGymWeightRoom card) {
super(card);
}
@Override
public MolderingGymWeightRoom copy() {
return new MolderingGymWeightRoom(this);
}
}

View file

@ -0,0 +1,60 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DrawNthCardTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
import mage.abilities.keyword.TrampleAbility;
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.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MoonGirlAndDevilDinosaur extends CardImpl {
public MoonGirlAndDevilDinosaur(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DINOSAUR);
this.subtype.add(SubType.HERO);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever you draw your second card each turn, until end of turn, Moon Girl and Devil Dinosaur's base power and toughness become 6/6 and they gain trample.
Ability ability = new DrawNthCardTriggeredAbility(
new SetBasePowerToughnessSourceEffect(6, 6, Duration.EndOfTurn)
.setText("until end of turn, {this}'s base power and toughness become 6/6")
);
ability.addEffect(new GainAbilitySourceEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn
).setText("and they gain trample"));
this.addAbility(ability);
// Whenever an artifact you control enters, draw a card. This ability triggers only once each turn.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT
).setTriggersLimitEachTurn(1));
}
private MoonGirlAndDevilDinosaur(final MoonGirlAndDevilDinosaur card) {
super(card);
}
@Override
public MoonGirlAndDevilDinosaur copy() {
return new MoonGirlAndDevilDinosaur(this);
}
}

View file

@ -1,43 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author fireshoes
*/
public final class MoonriseIntruder extends CardImpl {
public MoonriseIntruder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.color.setRed(true);
// this card is the second face of double-faced card
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility());
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonrise Intruder.
this.addAbility(new WerewolfBackTriggeredAbility());
}
private MoonriseIntruder(final MoonriseIntruder card) {
super(card);
}
@Override
public MoonriseIntruder copy() {
return new MoonriseIntruder(this);
}
}

View file

@ -1,50 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.Mana;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID;
/**
* @author North
*/
public final class MoonscarredWerewolf extends CardImpl {
public MoonscarredWerewolf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.color.setGreen(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// this card is the second face of double-faced card
this.nightCard = true;
this.addAbility(VigilanceAbility.getInstance());
// {tap}: Add {G}{G}.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(2), new TapSourceCost()));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonscarred Werewolf.
this.addAbility(new WerewolfBackTriggeredAbility());
}
private MoonscarredWerewolf(final MoonscarredWerewolf card) {
super(card);
}
@Override
public MoonscarredWerewolf copy() {
return new MoonscarredWerewolf(this);
}
}

View file

@ -40,7 +40,7 @@ public final class MoraugFuryOfAkoum extends CardImpl {
this.addAbility(new SimpleStaticAbility(new MoraugFuryOfAkoumBoostEffect()));
// Landfall Whenever a land you control enters, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control.
this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOUR), new MoraugFuryOfAkoumWatcher());
this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOURS), new MoraugFuryOfAkoumWatcher());
}
private MoraugFuryOfAkoum(final MoraugFuryOfAkoum card) {

View file

@ -1,51 +0,0 @@
package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.PutCards;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author xenohedron
*/
public final class MycoidMaze extends CardImpl {
public MycoidMaze(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.subtype.add(SubType.CAVE);
// (Transforms from Twists and Turns.)
this.nightCard = true;
// {T}: Add {G}.
this.addAbility(new GreenManaAbility());
// {3}{G}, {T}: Look at the top four cards of your library. You may reveal a creature card from among them and put that card into your hand. Put the rest on the bottom of your library in a random order.
Ability ability = new SimpleActivatedAbility(new LookLibraryAndPickControllerEffect(
4, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM
), new ManaCostsImpl<>("{3}{G}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private MycoidMaze(final MycoidMaze card) {
super(card);
}
@Override
public MycoidMaze copy() {
return new MycoidMaze(this);
}
}

Some files were not shown because too many files have changed in this diff Show more