forked from External/mage
Merge pull request 'master' (#39) from External/mage:master into master
All checks were successful
/ build_release (push) Successful in 15m40s
All checks were successful
/ build_release (push) Successful in 15m40s
Reviewed-on: #39
This commit is contained in:
commit
220763b685
68 changed files with 2739 additions and 235 deletions
64
Mage.Sets/src/mage/cards/a/AangsJourney.java
Normal file
64
Mage.Sets/src/mage/cards/a/AangsJourney.java
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||||
|
import mage.abilities.keyword.KickerAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
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.filter.predicate.Predicate;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||||
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class AangsJourney extends CardImpl {
|
||||||
|
|
||||||
|
private static final Predicate<Card> predicate = Predicates.and(
|
||||||
|
SuperType.BASIC.getPredicate(),
|
||||||
|
CardType.LAND.getPredicate()
|
||||||
|
);
|
||||||
|
|
||||||
|
public AangsJourney(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.LESSON);
|
||||||
|
|
||||||
|
// Kicker {2}
|
||||||
|
this.addAbility(new KickerAbility("{2}"));
|
||||||
|
|
||||||
|
// Search your library for a basic land card. If this spell was kicked, instead search your library for a basic land card and a Shrine card. Reveal those cards, put them into your hand, then shuffle.
|
||||||
|
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
|
||||||
|
new SearchLibraryPutInHandEffect(new TargetCardAndOrCardInLibrary(
|
||||||
|
predicate, SubType.SHRINE.getPredicate(),
|
||||||
|
"a basic land card and/or a Shrine card"
|
||||||
|
), true),
|
||||||
|
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true),
|
||||||
|
KickedCondition.ONCE, "search your library for a basic land card. If this spell was kicked, " +
|
||||||
|
"instead search your library for a basic land card and a Shrine card. " +
|
||||||
|
"Reveal those cards, put them into your hand, then shuffle"
|
||||||
|
));
|
||||||
|
|
||||||
|
// You gain 2 life.
|
||||||
|
this.getSpellAbility().addEffect(new GainLifeEffect(2).concatBy("<br>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AangsJourney(final AangsJourney card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AangsJourney copy() {
|
||||||
|
return new AangsJourney(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,6 +57,12 @@ class AlpineMoonEffect extends ContinuousEffectImpl {
|
||||||
this.staticText = "lands your opponents control with the chosen name "
|
this.staticText = "lands your opponents control with the chosen name "
|
||||||
+ "lose all land types and abilities, "
|
+ "lose all land types and abilities, "
|
||||||
+ "and they gain \"{T}: Add one mana of any color.\"";
|
+ "and they gain \"{T}: Add one mana of any color.\"";
|
||||||
|
addDependedToType(DependencyType.BecomeMountain);
|
||||||
|
addDependedToType(DependencyType.BecomeForest);
|
||||||
|
addDependedToType(DependencyType.BecomeIsland);
|
||||||
|
addDependedToType(DependencyType.BecomeSwamp);
|
||||||
|
addDependedToType(DependencyType.BecomePlains);
|
||||||
|
addDependedToType(DependencyType.BecomeNonbasicLand);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AlpineMoonEffect(final AlpineMoonEffect effect) {
|
private AlpineMoonEffect(final AlpineMoonEffect effect) {
|
||||||
|
|
@ -84,9 +90,6 @@ class AlpineMoonEffect extends ContinuousEffectImpl {
|
||||||
for (Permanent land : game.getBattlefield().getActivePermanents(filter2, source.getControllerId(), game)) {
|
for (Permanent land : game.getBattlefield().getActivePermanents(filter2, source.getControllerId(), game)) {
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
case TypeChangingEffects_4:
|
case TypeChangingEffects_4:
|
||||||
// 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects
|
|
||||||
// So the ability removing has to be done before Layer 6
|
|
||||||
land.removeAllAbilities(source.getSourceId(), game);
|
|
||||||
land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
|
land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
|
||||||
break;
|
break;
|
||||||
case AbilityAddingRemovingEffects_6:
|
case AbilityAddingRemovingEffects_6:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
|
|
@ -16,6 +15,8 @@ import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
|
|
@ -29,7 +30,7 @@ public final class AnHavvaConstable extends CardImpl {
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// An-Havva Constable's toughness is equal to 1 plus the number of green creatures on the battlefield.
|
// An-Havva Constable's toughness is equal to 1 plus the number of green creatures on the battlefield.
|
||||||
this.addAbility(new SimpleStaticAbility(new AnHavvaConstableEffect()));
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new AnHavvaConstableEffect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnHavvaConstable(final AnHavvaConstable card) {
|
private AnHavvaConstable(final AnHavvaConstable card) {
|
||||||
|
|
@ -72,7 +73,7 @@ class AnHavvaConstableEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
||||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||||
int numberOfGreenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source, game);
|
int numberOfGreenCreatures = game.getBattlefield().count(filter, source.getControllerId(), source, game);
|
||||||
|
|
||||||
mageObject.getToughness().setModifiedBaseValue(1 + numberOfGreenCreatures);
|
mageObject.getToughness().setModifiedBaseValue(1 + numberOfGreenCreatures);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ class BottleCapBlastEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
UUID target = getTargetPointer().getFirst(game, source);
|
UUID targetId = getTargetPointer().getFirst(game, source);
|
||||||
Player player = game.getPlayer(target);
|
Player player = game.getPlayer(targetId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(5, source, game);
|
player.damage(5, source, game);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -72,11 +72,10 @@ class BottleCapBlastEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = Math.min(permanent.getLethalDamage(source.getSourceId(), game), 5);
|
int excess = permanent.damageWithExcess(5, source, game);
|
||||||
permanent.damage(5, source.getSourceId(), source, game);
|
if (excess > 0) {
|
||||||
if (lethal < 5) {
|
|
||||||
new TreasureToken().putOntoBattlefield(
|
new TreasureToken().putOntoBattlefield(
|
||||||
5 - lethal, game, source, source.getControllerId(), true, false
|
excess, game, source, source.getControllerId(), true, false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package mage.cards.c;
|
package mage.cards.c;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.keyword.DiscoverEffect;
|
import mage.abilities.effects.keyword.DiscoverEffect;
|
||||||
|
|
@ -9,19 +7,18 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.StaticFilters;
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.Target;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import static mage.filter.StaticFilters.FILTER_ANOTHER_CREATURE_TARGET_2;
|
import static mage.filter.StaticFilters.FILTER_ANOTHER_CREATURE_TARGET_2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jimga150
|
* @author jimga150
|
||||||
*/
|
*/
|
||||||
public final class ContestOfClaws extends CardImpl {
|
public final class ContestOfClaws extends CardImpl {
|
||||||
|
|
@ -29,14 +26,10 @@ public final class ContestOfClaws extends CardImpl {
|
||||||
public ContestOfClaws(UUID ownerId, CardSetInfo setInfo) {
|
public ContestOfClaws(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
|
||||||
|
|
||||||
|
|
||||||
// Target creature you control deals damage equal to its power to another target creature. If excess damage was dealt this way, discover X, where X is that excess damage.
|
// Target creature you control deals damage equal to its power to another target creature. If excess damage was dealt this way, discover X, where X is that excess damage.
|
||||||
this.getSpellAbility().addEffect(new ContestOfClawsDamageEffect());
|
this.getSpellAbility().addEffect(new ContestOfClawsDamageEffect());
|
||||||
Target target = new TargetControlledCreaturePermanent().setTargetTag(1);
|
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent().setTargetTag(1));
|
||||||
this.getSpellAbility().addTarget(target);
|
this.getSpellAbility().addTarget(new TargetPermanent(FILTER_ANOTHER_CREATURE_TARGET_2).setTargetTag(2));
|
||||||
|
|
||||||
Target target2 = new TargetPermanent(FILTER_ANOTHER_CREATURE_TARGET_2).setTargetTag(2);
|
|
||||||
this.getSpellAbility().addTarget(target2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContestOfClaws(final ContestOfClaws card) {
|
private ContestOfClaws(final ContestOfClaws card) {
|
||||||
|
|
@ -74,22 +67,13 @@ class ContestOfClawsDamageEffect extends OneShotEffect {
|
||||||
if (ownCreature == null || targetCreature == null) {
|
if (ownCreature == null || targetCreature == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int damage = ownCreature.getPower().getValue();
|
int excess = targetCreature.damageWithExcess( ownCreature.getPower().getValue(), ownCreature.getId(), source, game);
|
||||||
int lethalDamage = targetCreature.getLethalDamage(source.getSourceId(), game);
|
if (excess > 0) {
|
||||||
targetCreature.damage(damage, ownCreature.getId(), source, game, false, true);
|
Optional.ofNullable(source)
|
||||||
|
.map(Controllable::getControllerId)
|
||||||
if (damage < lethalDamage){
|
.map(game::getPlayer)
|
||||||
return true;
|
.ifPresent(player -> DiscoverEffect.doDiscover(player, excess, game, source));
|
||||||
}
|
}
|
||||||
int discoverValue = damage - lethalDamage;
|
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
|
||||||
|
|
||||||
if (player == null){
|
|
||||||
// If somehow this case is hit, the damage still technically happened, so i guess it applied?
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DiscoverEffect.doDiscover(player, discoverValue, game, source);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class DarkImpostorContinuousEffect extends ContinuousEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source, 1));
|
||||||
if (permanent == null || exileZone == null || exileZone.isEmpty()) {
|
if (permanent == null || exileZone == null || exileZone.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
|
@ -16,14 +15,14 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterCreatureCard;
|
|
||||||
import mage.filter.common.FilterLandCard;
|
import mage.filter.common.FilterLandCard;
|
||||||
import mage.filter.predicate.Predicates;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.target.common.TargetCardInGraveyard;
|
import mage.target.common.TargetCardInGraveyard;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class EvraHalcyonWitnessEffect extends OneShotEffect {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null && player.isLifeTotalCanChange()) {
|
if (player != null && player.isLifeTotalCanChange()) {
|
||||||
Permanent perm = game.getPermanent(source.getSourceId());
|
Permanent perm = game.getPermanent(source.getSourceId());
|
||||||
if (perm != null) {
|
if (perm != null && perm.isCreature(game)) {
|
||||||
int amount = perm.getPower().getValue();
|
int amount = perm.getPower().getValue();
|
||||||
int life = player.getLife();
|
int life = player.getLife();
|
||||||
if (life == amount) {
|
if (life == amount) {
|
||||||
|
|
|
||||||
158
Mage.Sets/src/mage/cards/f/FireLordSozin.java
Normal file
158
Mage.Sets/src/mage/cards/f/FireLordSozin.java
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
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 + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,6 @@ import mage.util.CardUtil;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author ciaccona007
|
* @author ciaccona007
|
||||||
*/
|
*/
|
||||||
public final class GoblinNegotiation extends CardImpl {
|
public final class GoblinNegotiation extends CardImpl {
|
||||||
|
|
@ -62,13 +61,11 @@ class GoblinNegotiationEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int damage = CardUtil.getSourceCostsTag(game, source, "X", 0);
|
int excess = permanent.damageWithExcess(
|
||||||
int lethal = Math.min(permanent.getLethalDamage(source.getSourceId(), game), damage);
|
CardUtil.getSourceCostsTag(game, source, "X", 0), source, game
|
||||||
permanent.damage(damage, source.getSourceId(), source, game);
|
|
||||||
if (damage > lethal) {
|
|
||||||
new GoblinToken().putOntoBattlefield(
|
|
||||||
damage - lethal, game, source, source.getControllerId()
|
|
||||||
);
|
);
|
||||||
|
if (excess > 0) {
|
||||||
|
new GoblinToken().putOntoBattlefield(excess, game, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
Mage.Sets/src/mage/cards/h/HakodaSelflessCommander.java
Normal file
72
Mage.Sets/src/mage/cards/h/HakodaSelflessCommander.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.cards.h;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.PlayFromTopOfLibraryEffect;
|
||||||
|
import mage.abilities.keyword.IndestructibleAbility;
|
||||||
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class HakodaSelflessCommander extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCard filter = new FilterCard(SubType.ALLY, "Ally spells");
|
||||||
|
|
||||||
|
public HakodaSelflessCommander(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.subtype.add(SubType.WARRIOR);
|
||||||
|
this.subtype.add(SubType.ALLY);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
|
// Vigilance
|
||||||
|
this.addAbility(VigilanceAbility.getInstance());
|
||||||
|
|
||||||
|
// You may look at the top card of your library any time.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
|
||||||
|
|
||||||
|
// You may cast Ally spells from the top of your library.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new PlayFromTopOfLibraryEffect(filter)));
|
||||||
|
|
||||||
|
// Sacrifice Hakoda: Creatures you control get +0/+5 and gain indestructible until end of turn.
|
||||||
|
Ability ability = new SimpleActivatedAbility(
|
||||||
|
new BoostControlledEffect(0, 5, Duration.EndOfTurn)
|
||||||
|
.setText("creatures you control get +0/+5"),
|
||||||
|
new SacrificeSourceCost()
|
||||||
|
);
|
||||||
|
ability.addEffect(new GainAbilityAllEffect(
|
||||||
|
IndestructibleAbility.getInstance(), Duration.EndOfTurn,
|
||||||
|
StaticFilters.FILTER_CONTROLLED_CREATURE
|
||||||
|
).setText("and gain indestructible until end of turn"));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HakodaSelflessCommander(final HakodaSelflessCommander card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HakodaSelflessCommander copy() {
|
||||||
|
return new HakodaSelflessCommander(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
|
@ -29,6 +30,8 @@ public final class HaruHiddenTalent extends CardImpl {
|
||||||
|
|
||||||
public HaruHiddenTalent(UUID ownerId, CardSetInfo setInfo) {
|
public HaruHiddenTalent(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
this.subtype.add(SubType.PEASANT);
|
this.subtype.add(SubType.PEASANT);
|
||||||
this.subtype.add(SubType.ALLY);
|
this.subtype.add(SubType.ALLY);
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,11 @@ class HellToPayEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int damage = CardUtil.getSourceCostsTag(game, source, "X", 0);
|
int excess = permanent.damageWithExcess(
|
||||||
int lethal = Math.min(permanent.getLethalDamage(source.getSourceId(), game), damage);
|
CardUtil.getSourceCostsTag(game, source, "X", 0), source, game
|
||||||
permanent.damage(damage, source.getSourceId(), source, game);
|
|
||||||
if (damage > lethal) {
|
|
||||||
new TreasureToken().putOntoBattlefield(
|
|
||||||
damage - lethal, game, source, source.getControllerId(), true, false
|
|
||||||
);
|
);
|
||||||
|
if (excess > 0) {
|
||||||
|
new TreasureToken().putOntoBattlefield(excess, game, source, source.getControllerId(), true, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
84
Mage.Sets/src/mage/cards/h/HowToStartARiot.java
Normal file
84
Mage.Sets/src/mage/cards/h/HowToStartARiot.java
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
package mage.cards.h;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.target.targetpointer.SecondTargetPointer;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class HowToStartARiot extends CardImpl {
|
||||||
|
|
||||||
|
public HowToStartARiot(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.LESSON);
|
||||||
|
|
||||||
|
// Target creature gains menace until end of turn.
|
||||||
|
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(new MenaceAbility(false)));
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
|
|
||||||
|
// Creatures target player controls get +2/+0 until end of turn.
|
||||||
|
this.getSpellAbility().addEffect(new HowToStartARiotEffect());
|
||||||
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private HowToStartARiot(final HowToStartARiot card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HowToStartARiot copy() {
|
||||||
|
return new HowToStartARiot(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HowToStartARiotEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
HowToStartARiotEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.setTargetPointer(new SecondTargetPointer());
|
||||||
|
staticText = "creatures target player controls get +2/+0 until end of turn";
|
||||||
|
this.concatBy("<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private HowToStartARiotEffect(final HowToStartARiotEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HowToStartARiotEffect copy() {
|
||||||
|
return new HowToStartARiotEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||||
|
filter.add(new ControllerIdPredicate(player.getId()));
|
||||||
|
game.addEffect(new BoostAllEffect(
|
||||||
|
2, 0, Duration.EndOfTurn, filter, false
|
||||||
|
), source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -55,14 +55,13 @@ class LacerateFleshEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = Math.min(permanent.getLethalDamage(source.getSourceId(), game), 4);
|
int excess = permanent.damageWithExcess(4, source, game);
|
||||||
permanent.damage(4, source.getSourceId(), source, game);
|
if (excess > 0) {
|
||||||
if (lethal < 4) {
|
new BloodToken().putOntoBattlefield(excess, game, source);
|
||||||
new BloodToken().putOntoBattlefield(4 - lethal, game, source);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
Mage.Sets/src/mage/cards/l/LongFengGrandSecretariat.java
Normal file
72
Mage.Sets/src/mage/cards/l/LongFengGrandSecretariat.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.cards.l;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class LongFengGrandSecretariat extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterControlledPermanent("another creature you control or a land you control");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(LongFengGrandSecretariatPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LongFengGrandSecretariat(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B/G}{B/G}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.subtype.add(SubType.ADVISOR);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Whenever another creature you control or a land you control is put into a graveyard from the battlefield, put a +1/+1 counter on target creature you control.
|
||||||
|
Ability ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility(
|
||||||
|
new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
|
||||||
|
false, filter, false
|
||||||
|
);
|
||||||
|
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LongFengGrandSecretariat(final LongFengGrandSecretariat card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LongFengGrandSecretariat copy() {
|
||||||
|
return new LongFengGrandSecretariat(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LongFengGrandSecretariatPredicate implements ObjectSourcePlayerPredicate<MageObject> {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(ObjectSourcePlayer<MageObject> input, Game game) {
|
||||||
|
return input.getObject().isLand(game)
|
||||||
|
|| input.getObject().isCreature(game)
|
||||||
|
&& AnotherPredicate.instance.apply(input, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -126,36 +126,22 @@ class MegatronDestructiveForceReflexiveEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
|
|
||||||
if (sourcePermanent == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value < 1) {
|
if (value < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int excess = permanent.damageWithExcess(value, source, game);
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
if (excess < 1) {
|
||||||
int excess = value - lethal;
|
|
||||||
if (excess <= 0) {
|
|
||||||
// no excess damage.
|
|
||||||
permanent.damage(value, source.getSourceId(), source, game);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// excess damage. dealing excess to controller's instead. And convert Megatron.
|
|
||||||
permanent.damage(lethal, source.getSourceId(), source, game);
|
|
||||||
Player player = game.getPlayer(permanent.getControllerId());
|
Player player = game.getPlayer(permanent.getControllerId());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.damage(excess, source, game);
|
player.damage(excess, source, game);
|
||||||
}
|
}
|
||||||
new TransformSourceEffect().apply(game, source);
|
new TransformSourceEffect().apply(game, source);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
132
Mage.Sets/src/mage/cards/m/MomoFriendlyFlier.java
Normal file
132
Mage.Sets/src/mage/cards/m/MomoFriendlyFlier.java
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
package mage.cards.m;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.decorator.ConditionalCostModificationEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
|
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
|
||||||
|
import mage.abilities.hint.ConditionHint;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class MomoFriendlyFlier extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCard filter = new FilterCard();
|
||||||
|
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent("another creature you control with flying");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.not(SubType.LEMUR.getPredicate()));
|
||||||
|
filter.add(new AbilityPredicate(FlyingAbility.class));
|
||||||
|
filter2.add(new AbilityPredicate(FlyingAbility.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MomoFriendlyFlier(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.LEMUR);
|
||||||
|
this.subtype.add(SubType.BAT);
|
||||||
|
this.subtype.add(SubType.ALLY);
|
||||||
|
this.power = new MageInt(1);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// The first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new ConditionalCostModificationEffect(
|
||||||
|
new SpellsCostReductionControllerEffect(filter, 1), MomoFriendlyFlierCondition.instance,
|
||||||
|
"the first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast"
|
||||||
|
)).addHint(MomoFriendlyFlierCondition.getHint()), new MomoFriendlyFlierWatcher());
|
||||||
|
|
||||||
|
// Whenever another creature you control with flying enters, Momo gets +1/+1 until end of turn.
|
||||||
|
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
|
||||||
|
new BoostSourceEffect(1, 1, Duration.EndOfTurn), filter2
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private MomoFriendlyFlier(final MomoFriendlyFlier card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MomoFriendlyFlier copy() {
|
||||||
|
return new MomoFriendlyFlier(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MomoFriendlyFlierCondition implements Condition {
|
||||||
|
instance;
|
||||||
|
private static final Hint hint = new ConditionHint(
|
||||||
|
instance, "You haven't cast a non-Lemur creature spell with flying during your turn yet"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Hint getHint() {
|
||||||
|
return hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return game.isActivePlayer(source.getControllerId())
|
||||||
|
&& !MomoFriendlyFlierWatcher.checkPlayer(game, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MomoFriendlyFlierWatcher extends Watcher {
|
||||||
|
|
||||||
|
private final Set<UUID> set = new HashSet<>();
|
||||||
|
|
||||||
|
MomoFriendlyFlierWatcher() {
|
||||||
|
super(WatcherScope.GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void watch(GameEvent event, Game game) {
|
||||||
|
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Spell spell = game.getSpell(event.getTargetId());
|
||||||
|
if (spell != null
|
||||||
|
&& spell.isCreature(game)
|
||||||
|
&& !spell.hasSubtype(SubType.LEMUR, game)
|
||||||
|
&& spell.getAbilities(game).containsClass(FlyingAbility.class)) {
|
||||||
|
set.add(spell.getControllerId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
set.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean checkPlayer(Game game, Ability source) {
|
||||||
|
return game
|
||||||
|
.getState()
|
||||||
|
.getWatcher(MomoFriendlyFlierWatcher.class)
|
||||||
|
.set
|
||||||
|
.contains(source.getControllerId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -80,9 +80,8 @@ class NahirisWarcraftingEffect extends OneShotEffect {
|
||||||
if (player == null || permanent == null) {
|
if (player == null || permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
int excess = permanent.damageWithExcess(5, source, game);
|
||||||
int excess = permanent.damage(5, source, game) - lethal;
|
if (excess < 1) {
|
||||||
if (excess <= 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, excess));
|
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, excess));
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package mage.cards.o;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -61,10 +60,8 @@ class OrbitalPlungeEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
if (permanent.damageWithExcess(6, source, game) > 0) {
|
||||||
permanent.damage(6, source.getSourceId(), source, game);
|
new LanderToken().putOntoBattlefield(1, game, source);
|
||||||
if (lethal < 6) {
|
|
||||||
new CreateTokenEffect(new LanderToken()).apply(game, source);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,18 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.StaticFilters;
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.targetpointer.EachTargetPointer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static mage.filter.StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL;
|
import static mage.filter.StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL;
|
||||||
|
|
||||||
|
|
@ -47,6 +50,7 @@ class RamThroughEffect extends OneShotEffect {
|
||||||
|
|
||||||
RamThroughEffect() {
|
RamThroughEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
|
this.setTargetPointer(new EachTargetPointer());
|
||||||
staticText = "Target creature you control deals damage equal to its power to target creature you don't control. " +
|
staticText = "Target creature you control deals damage equal to its power to target creature you don't control. " +
|
||||||
"If the creature you control has trample, excess damage is dealt to that creature's controller instead.";
|
"If the creature you control has trample, excess damage is dealt to that creature's controller instead.";
|
||||||
}
|
}
|
||||||
|
|
@ -62,29 +66,31 @@ class RamThroughEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
if (source.getTargets().size() != 2) {
|
List<Permanent> permanents = this
|
||||||
throw new IllegalStateException("It must have two targets, but found " + source.getTargets().size());
|
.getTargetPointer()
|
||||||
}
|
.getTargets(game, source)
|
||||||
|
.stream()
|
||||||
Permanent myPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
.map(game::getPermanent)
|
||||||
Permanent anotherPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
if (myPermanent == null || anotherPermanent == null) {
|
if (permanents.size() < 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int power = myPermanent.getPower().getValue();
|
Permanent permanent = permanents.get(0);
|
||||||
|
int power = permanent.getPower().getValue();
|
||||||
if (power < 1) {
|
if (power < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!myPermanent.getAbilities().containsKey(TrampleAbility.getInstance().getId())) {
|
Permanent creature = permanents.get(1);
|
||||||
return anotherPermanent.damage(power, myPermanent.getId(), source, game, false, true) > 0;
|
if (!permanent.hasAbility(TrampleAbility.getInstance(), game)) {
|
||||||
|
return creature.damage(power, permanent.getId(), source, game) > 0;
|
||||||
}
|
}
|
||||||
int lethal = anotherPermanent.getLethalDamage(myPermanent.getId(), game);
|
int excess = creature.damageWithExcess(power, permanent.getId(), source, game);
|
||||||
lethal = Math.min(lethal, power);
|
if (excess > 0) {
|
||||||
anotherPermanent.damage(lethal, myPermanent.getId(), source, game);
|
Optional.ofNullable(creature)
|
||||||
Player player = game.getPlayer(anotherPermanent.getControllerId());
|
.map(Controllable::getControllerId)
|
||||||
if (player != null && lethal < power) {
|
.map(game::getPlayer)
|
||||||
player.damage(power - lethal, myPermanent.getId(), source, game);
|
.ifPresent(player -> player.damage(excess, permanent.getId(), source, game));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
Mage.Sets/src/mage/cards/r/RazorRings.java
Normal file
72
Mage.Sets/src/mage/cards/r/RazorRings.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.cards.r;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.game.Controllable;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.common.TargetAttackingOrBlockingCreature;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class RazorRings extends CardImpl {
|
||||||
|
|
||||||
|
public RazorRings(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
|
||||||
|
|
||||||
|
// Razor Rings deals 4 damage to target attacking or blocking creature. You gain life equal to the excess damage dealt this way.
|
||||||
|
this.getSpellAbility().addEffect(new RazorRingsEffect());
|
||||||
|
this.getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature());
|
||||||
|
}
|
||||||
|
|
||||||
|
private RazorRings(final RazorRings card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RazorRings copy() {
|
||||||
|
return new RazorRings(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RazorRingsEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
RazorRingsEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "{this} deals 4 damage to target attacking or blocking creature. " +
|
||||||
|
"You gain life equal to the excess damage dealt this way";
|
||||||
|
}
|
||||||
|
|
||||||
|
private RazorRingsEffect(final RazorRingsEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RazorRingsEffect copy() {
|
||||||
|
return new RazorRingsEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
|
if (permanent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int excess = permanent.damageWithExcess(4, source, game);
|
||||||
|
if (excess > 0) {
|
||||||
|
Optional.ofNullable(source)
|
||||||
|
.map(Controllable::getControllerId)
|
||||||
|
.map(game::getPlayer)
|
||||||
|
.ifPresent(player -> player.gainLife(excess, game, source));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -129,7 +129,6 @@ class RexCyberhoundContinuousEffect extends ContinuousEffectImpl {
|
||||||
for (Ability ability : card.getAbilities(game)) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability.isActivatedAbility()) {
|
if (ability.isActivatedAbility()) {
|
||||||
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
|
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
|
||||||
copyAbility.setMaxActivationsPerTurn(1);
|
|
||||||
perm.addAbility(copyAbility, source.getSourceId(), game, true);
|
perm.addAbility(copyAbility, source.getSourceId(), game, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
71
Mage.Sets/src/mage/cards/s/SerpentOfThePass.java
Normal file
71
Mage.Sets/src/mage/cards/s/SerpentOfThePass.java
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.condition.common.CardsInControllerGraveyardCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalAsThoughEffect;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
|
||||||
|
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect;
|
||||||
|
import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
|
import mage.abilities.hint.ValueHint;
|
||||||
|
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 mage.filter.FilterCard;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class SerpentOfThePass extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new CardsInControllerGraveyardCondition(3, new FilterCard(SubType.LESSON));
|
||||||
|
private static final Hint hint = new ValueHint(
|
||||||
|
"Lesson cards in your graveyard", new CardsInControllerGraveyardCount(new FilterCard(SubType.LESSON))
|
||||||
|
);
|
||||||
|
private static final FilterCard filter = new FilterCard("noncreature, nonland card");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||||
|
filter.add(Predicates.not(CardType.LAND.getPredicate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final DynamicValue xValue = new CardsInControllerGraveyardCount(filter);
|
||||||
|
private static final Hint hint2 = new ValueHint("Noncreature, nonland cards in your graveyard", xValue);
|
||||||
|
|
||||||
|
public SerpentOfThePass(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.SERPENT);
|
||||||
|
this.power = new MageInt(6);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
|
// If there are three or more Lesson cards in your graveyard, you may cast this spell as though it had flash.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConditionalAsThoughEffect(
|
||||||
|
new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame), condition
|
||||||
|
).setText("if there are three or more Lesson cards in your graveyard, " +
|
||||||
|
"you may cast this spell as though it had flash.")).addHint(hint));
|
||||||
|
|
||||||
|
// This spell costs {1} less to cast for each noncreature, nonland card in your graveyard.
|
||||||
|
this.addAbility(new SimpleStaticAbility(
|
||||||
|
Zone.ALL, new SpellCostReductionForEachSourceEffect(1, xValue)
|
||||||
|
).setRuleAtTheTop(true).addHint(hint2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SerpentOfThePass(final SerpentOfThePass card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerpentOfThePass copy() {
|
||||||
|
return new SerpentOfThePass(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
75
Mage.Sets/src/mage/cards/s/SokkaLateralStrategist.java
Normal file
75
Mage.Sets/src/mage/cards/s/SokkaLateralStrategist.java
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
|
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.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class SokkaLateralStrategist extends CardImpl {
|
||||||
|
|
||||||
|
public SokkaLateralStrategist(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/U}{W/U}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.subtype.add(SubType.WARRIOR);
|
||||||
|
this.subtype.add(SubType.ALLY);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// Vigilance
|
||||||
|
this.addAbility(VigilanceAbility.getInstance());
|
||||||
|
|
||||||
|
// Whenever Sokka and at least one other creature attack, draw a card.
|
||||||
|
this.addAbility(new SokkaLateralStrategistTriggeredAbility());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SokkaLateralStrategist(final SokkaLateralStrategist card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SokkaLateralStrategist copy() {
|
||||||
|
return new SokkaLateralStrategist(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SokkaLateralStrategistTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
SokkaLateralStrategistTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1));
|
||||||
|
this.setTriggerPhrase("Whenever {this} and at least one other creature attack, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SokkaLateralStrategistTriggeredAbility(final SokkaLateralStrategistTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SokkaLateralStrategistTriggeredAbility copy() {
|
||||||
|
return new SokkaLateralStrategistTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
return game.getCombat().getAttackers().size() >= 2 && game.getCombat().getAttackers().contains(getSourceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,33 +1,31 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.keyword.FearAbility;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.ManaWasSpentCondition;
|
import mage.abilities.condition.common.ManaWasSpentCondition;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.SacrificeSourceUnlessConditionEffect;
|
import mage.abilities.effects.common.SacrificeSourceUnlessConditionEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
|
import mage.abilities.keyword.FearAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class SquealingDevil extends CardImpl {
|
public final class SquealingDevil extends CardImpl {
|
||||||
|
|
@ -76,25 +74,23 @@ class SquealingDevilEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null || !player.chooseUse(Outcome.BoostCreature, "Pay {X}?", source, game)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int xValue = player.announceX(0, Integer.MAX_VALUE, "Announce the value for {X} (pay to boost)", game, source, true);
|
||||||
ManaCosts cost = new ManaCostsImpl<>("{X}");
|
ManaCosts cost = new ManaCostsImpl<>("{X}");
|
||||||
if (player != null) {
|
cost.add(new GenericManaCost(xValue));
|
||||||
if (player.chooseUse(Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game)) {
|
if (!cost.pay(source, game, source, source.getControllerId(), false, null)) {
|
||||||
int costX = player.announceX(0, Integer.MAX_VALUE, "Announce the value for {X} (pay to boost)", game, source, true);
|
return false;
|
||||||
cost.add(new GenericManaCost(costX));
|
}
|
||||||
if (cost.pay(source, game, source, source.getControllerId(), false, null)) {
|
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
if (permanent == null) {
|
||||||
if (permanent != null && permanent.isCreature(game)) {
|
return false;
|
||||||
ContinuousEffect effect = new BoostTargetEffect(costX, 0, Duration.EndOfTurn);
|
}
|
||||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
game.addEffect(new BoostTargetEffect(xValue, 0, Duration.EndOfTurn)
|
||||||
game.addEffect(effect, source);
|
.setTargetPointer(new FixedTarget(permanent, game)), source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SquealingDevilEffect copy() {
|
public SquealingDevilEffect copy() {
|
||||||
|
|
|
||||||
|
|
@ -78,14 +78,19 @@ class StalwartSuccessorTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
int zccOffset = 0;
|
||||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||||
|
if (permanent == null) {
|
||||||
|
permanent = game.getPermanentEntering(event.getTargetId());
|
||||||
|
zccOffset = 1;
|
||||||
|
}
|
||||||
if (permanent == null
|
if (permanent == null
|
||||||
|| !permanent.isCreature(game)
|
|| !permanent.isCreature(game)
|
||||||
|| !permanent.isControlledBy(getControllerId())
|
|| !permanent.isControlledBy(getControllerId())
|
||||||
|| !StalwartSuccessorWatcher.checkCreature(permanent, event, game)) {
|
|| !StalwartSuccessorWatcher.checkCreature(permanent, event, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
this.getEffects().setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game) + zccOffset));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +106,11 @@ class StalwartSuccessorWatcher extends Watcher {
|
||||||
@Override
|
@Override
|
||||||
public void watch(GameEvent event, Game game) {
|
public void watch(GameEvent event, Game game) {
|
||||||
if (event.getType() == GameEvent.EventType.COUNTERS_ADDED) {
|
if (event.getType() == GameEvent.EventType.COUNTERS_ADDED) {
|
||||||
|
if (game.getPermanent(event.getTargetId()) == null) {
|
||||||
|
// permanent entering
|
||||||
|
Permanent permanent = game.getPermanentEntering(event.getTargetId());
|
||||||
|
map.putIfAbsent(new MageObjectReference(event.getTargetId(), permanent.getZoneChangeCounter(game) + 1, game), event.getId());
|
||||||
|
}
|
||||||
map.putIfAbsent(new MageObjectReference(event.getTargetId(), game), event.getId());
|
map.putIfAbsent(new MageObjectReference(event.getTargetId(), game), event.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
85
Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java
Normal file
85
Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
package mage.cards.t;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SagaAbility;
|
||||||
|
import mage.abilities.effects.Effects;
|
||||||
|
import mage.abilities.effects.common.ChooseACardNameEffect;
|
||||||
|
import mage.abilities.effects.common.DestroyAllEffect;
|
||||||
|
import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
|
||||||
|
import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect;
|
||||||
|
import mage.abilities.keyword.TransformAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SagaChapter;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class TheRiseOfSozin extends CardImpl {
|
||||||
|
|
||||||
|
public TheRiseOfSozin(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.SAGA);
|
||||||
|
this.secondSideCardClazz = mage.cards.f.FireLordSozin.class;
|
||||||
|
|
||||||
|
// (As this Saga enters and after your draw step, add a lore counter.)
|
||||||
|
SagaAbility sagaAbility = new SagaAbility(this);
|
||||||
|
|
||||||
|
// I -- Destroy all creatures.
|
||||||
|
sagaAbility.addChapterEffect(
|
||||||
|
this, SagaChapter.CHAPTER_I, new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES)
|
||||||
|
);
|
||||||
|
|
||||||
|
// II -- Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. Then that player shuffles.
|
||||||
|
sagaAbility.addChapterEffect(
|
||||||
|
this, SagaChapter.CHAPTER_II,
|
||||||
|
new Effects(
|
||||||
|
new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.ALL), new TheRiseOfSozinEffect()
|
||||||
|
), new TargetOpponent()
|
||||||
|
);
|
||||||
|
|
||||||
|
// III -- Exile this Saga, then return it to the battlefield transformed under your control.
|
||||||
|
this.addAbility(new TransformAbility());
|
||||||
|
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect());
|
||||||
|
this.addAbility(sagaAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheRiseOfSozin(final TheRiseOfSozin card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheRiseOfSozin copy() {
|
||||||
|
return new TheRiseOfSozin(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TheRiseOfSozinEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect {
|
||||||
|
|
||||||
|
TheRiseOfSozinEffect() {
|
||||||
|
super(true, "target opponent's", "up to four cards with that name", false, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheRiseOfSozinEffect(final TheRiseOfSozinEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheRiseOfSozinEffect copy() {
|
||||||
|
return new TheRiseOfSozinEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
String chosenCardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
|
||||||
|
return applySearchAndExile(game, source, chosenCardName, getTargetPointer().getFirst(game, source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -60,8 +60,7 @@ class TorchTheWitnessEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
if (permanent.damageWithExcess(2 * CardUtil.getSourceCostsTag(game, source, "X", 0), source, game) > 0) {
|
||||||
if (lethal < permanent.damage(2 * CardUtil.getSourceCostsTag(game, source, "X", 0), source, game)) {
|
|
||||||
InvestigateEffect.doInvestigate(source.getControllerId(), 1, game, source);
|
InvestigateEffect.doInvestigate(source.getControllerId(), 1, game, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class TreeOfPerditionEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player opponent = game.getPlayer(source.getFirstTarget());
|
Player opponent = game.getPlayer(source.getFirstTarget());
|
||||||
Permanent perm = game.getPermanent(source.getSourceId());
|
Permanent perm = game.getPermanent(source.getSourceId());
|
||||||
if (perm == null || opponent == null || !opponent.isLifeTotalCanChange()) {
|
if (perm == null || opponent == null || !opponent.isLifeTotalCanChange() || !perm.isCreature(game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class TreeOfRedemptionEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
Permanent perm = game.getPermanent(source.getSourceId());
|
Permanent perm = game.getPermanent(source.getSourceId());
|
||||||
if (perm == null || player == null || !player.isLifeTotalCanChange()) {
|
if (perm == null || player == null || !player.isLifeTotalCanChange() || !perm.isCreature(game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,10 @@ class UnleashTheInfernoEffect extends OneShotEffect {
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int lethal = Math.min(permanent.getLethalDamage(source.getSourceId(), game), 7);
|
int excess = permanent.damageWithExcess(7, source, game);
|
||||||
permanent.damage(7, source, game);
|
if (excess < 1) {
|
||||||
int excess = 7 - lethal;
|
return true;
|
||||||
if (excess > 0) {
|
}
|
||||||
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new DestroyTargetEffect(), false);
|
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new DestroyTargetEffect(), false);
|
||||||
FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent(
|
FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent(
|
||||||
"artifact or enchantment an opponent controls with mana value less than or equal to " + excess
|
"artifact or enchantment an opponent controls with mana value less than or equal to " + excess
|
||||||
|
|
@ -79,7 +79,6 @@ class UnleashTheInfernoEffect extends OneShotEffect {
|
||||||
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, excess + 1));
|
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, excess + 1));
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
game.fireReflexiveTriggeredAbility(ability, source);
|
game.fireReflexiveTriggeredAbility(ability, source);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.PlayLandOrCastSpellTriggeredAbility;
|
import mage.abilities.common.PlayLandOrCastSpellTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.effects.AsThoughEffectImpl;
|
import mage.abilities.effects.AsThoughEffectImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
|
@ -14,7 +17,6 @@ import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Controllable;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
@ -142,14 +144,16 @@ class UriangerAugureltPlayEffect extends AsThoughEffectImpl {
|
||||||
if (card.isLand(game)) {
|
if (card.isLand(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// TODO: This should ideally apply the reduction while the spell is being cast because effects that increase the cost apply first
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
Optional.ofNullable(source)
|
if (controller != null) {
|
||||||
.map(Controllable::getControllerId)
|
ManaCosts<ManaCost> newCost = CardUtil.reduceCost(card.getManaCost(), 2);
|
||||||
.map(game::getPlayer)
|
if (newCost.isEmpty()) {
|
||||||
.ifPresent(player -> player.setCastSourceIdWithAlternateMana(
|
newCost.add(new GenericManaCost(0));
|
||||||
card.getId(), CardUtil.reduceCost(card.getManaCost(), 2),
|
}
|
||||||
null, MageIdentifier.UriangerAugureltAlternateCast
|
controller.setCastSourceIdWithAlternateMana(
|
||||||
));
|
card.getId(), newCost, null, MageIdentifier.UriangerAugureltAlternateCast
|
||||||
|
);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetAnyTarget;
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,14 +93,11 @@ class VikyaScorchingStalwartEffect extends OneShotEffect {
|
||||||
if (!permanent.isCreature(game)) {
|
if (!permanent.isCreature(game)) {
|
||||||
return permanent.damage(amount, source, game) > 0;
|
return permanent.damage(amount, source, game) > 0;
|
||||||
}
|
}
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
if (permanent.damageWithExcess(amount, source, game) > 0) {
|
||||||
permanent.damage(amount, source.getSourceId(), source, game);
|
Optional.ofNullable(source)
|
||||||
if (lethal >= amount) {
|
.map(Controllable::getControllerId)
|
||||||
return true;
|
.map(game::getPlayer)
|
||||||
}
|
.ifPresent(player -> player.drawCards(1, source, game));
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
|
||||||
if (player != null) {
|
|
||||||
player.drawCards(1, source, game);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,26 @@
|
||||||
package mage.cards.w;
|
package mage.cards.w;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.StaticFilters;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.ElfWarriorToken;
|
import mage.game.permanent.token.ElfWarriorToken;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.targetpointer.EachTargetPointer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static mage.filter.StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL;
|
import static mage.filter.StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author bwsinger
|
* @author bwsinger
|
||||||
*/
|
*/
|
||||||
public final class WindswiftSlice extends CardImpl {
|
public final class WindswiftSlice extends CardImpl {
|
||||||
|
|
@ -48,6 +49,7 @@ class WindswiftSliceEffect extends OneShotEffect {
|
||||||
|
|
||||||
WindswiftSliceEffect() {
|
WindswiftSliceEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
|
this.setTargetPointer(new EachTargetPointer());
|
||||||
staticText = "Target creature you control deals damage equal to its power to target " +
|
staticText = "Target creature you control deals damage equal to its power to target " +
|
||||||
"creature you don't control. Create a number of 1/1 green Elf Warrior creature " +
|
"creature you don't control. Create a number of 1/1 green Elf Warrior creature " +
|
||||||
"tokens equal to the amount of excess damage dealt this way.";
|
"tokens equal to the amount of excess damage dealt this way.";
|
||||||
|
|
@ -64,27 +66,26 @@ class WindswiftSliceEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent myPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
List<Permanent> permanents = this
|
||||||
Permanent anotherPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
|
.getTargetPointer()
|
||||||
|
.getTargets(game, source)
|
||||||
if (myPermanent == null || anotherPermanent == null) {
|
.stream()
|
||||||
|
.map(game::getPermanent)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (permanents.size() < 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Permanent permanent = permanents.get(0);
|
||||||
int power = myPermanent.getPower().getValue();
|
int power = permanent.getPower().getValue();
|
||||||
if (power < 1) {
|
if (power < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Permanent creature = permanents.get(1);
|
||||||
int lethal = anotherPermanent.getLethalDamage(myPermanent.getId(), game);
|
int excess = creature.damageWithExcess(power, permanent.getId(), source, game);
|
||||||
lethal = Math.min(lethal, power);
|
if (excess > 0) {
|
||||||
|
new ElfWarriorToken().putOntoBattlefield(excess, game, source);
|
||||||
anotherPermanent.damage(power, myPermanent.getId(), source, game);
|
|
||||||
|
|
||||||
if (lethal < power) {
|
|
||||||
new ElfWarriorToken().putOntoBattlefield(power - lethal, game, source, source.getControllerId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
|
|
||||||
cards.add(new SetCardInfo("Aang's Iceberg", 336, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Aang's Iceberg", 336, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Aang's Iceberg", 5, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Aang's Iceberg", 5, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Aang's Journey", 1, Rarity.COMMON, mage.cards.a.AangsJourney.class));
|
||||||
cards.add(new SetCardInfo("Aang, Master of Elements", 207, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Aang, Master of Elements", 207, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Aang, the Last Airbender", 4, Rarity.UNCOMMON, mage.cards.a.AangTheLastAirbender.class));
|
cards.add(new SetCardInfo("Aang, the Last Airbender", 4, Rarity.UNCOMMON, mage.cards.a.AangTheLastAirbender.class));
|
||||||
|
|
@ -55,6 +56,8 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Epic Downfall", 96, Rarity.UNCOMMON, mage.cards.e.EpicDownfall.class));
|
cards.add(new SetCardInfo("Epic Downfall", 96, Rarity.UNCOMMON, mage.cards.e.EpicDownfall.class));
|
||||||
cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Fire Lord Sozin", 117, Rarity.MYTHIC, mage.cards.f.FireLordSozin.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Fire Lord Sozin", 356, Rarity.MYTHIC, mage.cards.f.FireLordSozin.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class));
|
cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class));
|
||||||
|
|
@ -63,15 +66,19 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class));
|
cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class));
|
||||||
cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class));
|
cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class));
|
||||||
cards.add(new SetCardInfo("Flopsie, Bumi's Buddy", 179, Rarity.UNCOMMON, mage.cards.f.FlopsieBumisBuddy.class));
|
cards.add(new SetCardInfo("Flopsie, Bumi's Buddy", 179, Rarity.UNCOMMON, mage.cards.f.FlopsieBumisBuddy.class));
|
||||||
|
cards.add(new SetCardInfo("Forest", 286, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Geyser Leaper", 52, Rarity.COMMON, mage.cards.g.GeyserLeaper.class));
|
cards.add(new SetCardInfo("Geyser Leaper", 52, Rarity.COMMON, mage.cards.g.GeyserLeaper.class));
|
||||||
cards.add(new SetCardInfo("Giant Koi", 53, Rarity.COMMON, mage.cards.g.GiantKoi.class));
|
cards.add(new SetCardInfo("Giant Koi", 53, Rarity.COMMON, mage.cards.g.GiantKoi.class));
|
||||||
cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class));
|
cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class));
|
||||||
|
cards.add(new SetCardInfo("Hakoda, Selfless Commander", 366, Rarity.RARE, mage.cards.h.HakodaSelflessCommander.class));
|
||||||
cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class));
|
cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class));
|
||||||
cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class));
|
cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class));
|
||||||
cards.add(new SetCardInfo("Hei Bai, Spirit of Balance", 225, Rarity.UNCOMMON, mage.cards.h.HeiBaiSpiritOfBalance.class));
|
cards.add(new SetCardInfo("Hei Bai, Spirit of Balance", 225, Rarity.UNCOMMON, mage.cards.h.HeiBaiSpiritOfBalance.class));
|
||||||
cards.add(new SetCardInfo("Hog-Monkey", 104, Rarity.COMMON, mage.cards.h.HogMonkey.class));
|
cards.add(new SetCardInfo("Hog-Monkey", 104, Rarity.COMMON, mage.cards.h.HogMonkey.class));
|
||||||
|
cards.add(new SetCardInfo("How to Start a Riot", 140, Rarity.COMMON, mage.cards.h.HowToStartARiot.class));
|
||||||
cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class));
|
cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class));
|
||||||
|
cards.add(new SetCardInfo("Island", 283, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("It'll Quench Ya!", 58, Rarity.COMMON, mage.cards.i.ItllQuenchYa.class));
|
cards.add(new SetCardInfo("It'll Quench Ya!", 58, Rarity.COMMON, mage.cards.i.ItllQuenchYa.class));
|
||||||
cards.add(new SetCardInfo("Jeong Jeong's Deserters", 25, Rarity.COMMON, mage.cards.j.JeongJeongsDeserters.class));
|
cards.add(new SetCardInfo("Jeong Jeong's Deserters", 25, Rarity.COMMON, mage.cards.j.JeongJeongsDeserters.class));
|
||||||
|
|
@ -82,20 +89,26 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Katara, the Fearless", 350, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Katara, the Fearless", 350, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Katara, the Fearless", 361, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Katara, the Fearless", 361, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Lightning Strike", 146, Rarity.COMMON, mage.cards.l.LightningStrike.class));
|
cards.add(new SetCardInfo("Lightning Strike", 146, Rarity.COMMON, mage.cards.l.LightningStrike.class));
|
||||||
|
cards.add(new SetCardInfo("Long Feng, Grand Secretariat", 233, Rarity.UNCOMMON, mage.cards.l.LongFengGrandSecretariat.class));
|
||||||
cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class));
|
cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class));
|
||||||
cards.add(new SetCardInfo("Master Piandao", 28, Rarity.UNCOMMON, mage.cards.m.MasterPiandao.class));
|
cards.add(new SetCardInfo("Master Piandao", 28, Rarity.UNCOMMON, mage.cards.m.MasterPiandao.class));
|
||||||
cards.add(new SetCardInfo("Merchant of Many Hats", 110, Rarity.COMMON, mage.cards.m.MerchantOfManyHats.class));
|
cards.add(new SetCardInfo("Merchant of Many Hats", 110, Rarity.COMMON, mage.cards.m.MerchantOfManyHats.class));
|
||||||
|
cards.add(new SetCardInfo("Momo, Friendly Flier", 29, Rarity.RARE, mage.cards.m.MomoFriendlyFlier.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Momo, Friendly Flier", 317, Rarity.RARE, mage.cards.m.MomoFriendlyFlier.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Mongoose Lizard", 148, Rarity.COMMON, mage.cards.m.MongooseLizard.class));
|
cards.add(new SetCardInfo("Mongoose Lizard", 148, Rarity.COMMON, mage.cards.m.MongooseLizard.class));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 285, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class));
|
cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class));
|
||||||
cards.add(new SetCardInfo("Otter-Penguin", 67, Rarity.COMMON, mage.cards.o.OtterPenguin.class));
|
cards.add(new SetCardInfo("Otter-Penguin", 67, Rarity.COMMON, mage.cards.o.OtterPenguin.class));
|
||||||
cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class));
|
cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class));
|
||||||
cards.add(new SetCardInfo("Path to Redemption", 31, Rarity.COMMON, mage.cards.p.PathToRedemption.class));
|
cards.add(new SetCardInfo("Path to Redemption", 31, Rarity.COMMON, mage.cards.p.PathToRedemption.class));
|
||||||
cards.add(new SetCardInfo("Pillar Launch", 189, Rarity.COMMON, mage.cards.p.PillarLaunch.class));
|
cards.add(new SetCardInfo("Pillar Launch", 189, Rarity.COMMON, mage.cards.p.PillarLaunch.class));
|
||||||
|
cards.add(new SetCardInfo("Plains", 282, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class));
|
cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class));
|
||||||
cards.add(new SetCardInfo("Rabaroo Troop", 32, Rarity.COMMON, mage.cards.r.RabarooTroop.class));
|
cards.add(new SetCardInfo("Rabaroo Troop", 32, Rarity.COMMON, mage.cards.r.RabarooTroop.class));
|
||||||
cards.add(new SetCardInfo("Raucous Audience", 190, Rarity.COMMON, mage.cards.r.RaucousAudience.class));
|
cards.add(new SetCardInfo("Raucous Audience", 190, Rarity.COMMON, mage.cards.r.RaucousAudience.class));
|
||||||
|
cards.add(new SetCardInfo("Razor Rings", 33, Rarity.COMMON, mage.cards.r.RazorRings.class));
|
||||||
cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class));
|
cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class));
|
||||||
cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS));
|
||||||
|
|
@ -103,12 +116,17 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Rough Rhino Cavalry", 152, Rarity.COMMON, mage.cards.r.RoughRhinoCavalry.class));
|
cards.add(new SetCardInfo("Rough Rhino Cavalry", 152, Rarity.COMMON, mage.cards.r.RoughRhinoCavalry.class));
|
||||||
cards.add(new SetCardInfo("Rowdy Snowballers", 68, Rarity.COMMON, mage.cards.r.RowdySnowballers.class));
|
cards.add(new SetCardInfo("Rowdy Snowballers", 68, Rarity.COMMON, mage.cards.r.RowdySnowballers.class));
|
||||||
cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class));
|
cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class));
|
||||||
|
cards.add(new SetCardInfo("Serpent of the Pass", 70, Rarity.UNCOMMON, mage.cards.s.SerpentOfThePass.class));
|
||||||
cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class));
|
cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class));
|
||||||
cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 383, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 383, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Sokka, Lateral Strategist", 241, Rarity.UNCOMMON, mage.cards.s.SokkaLateralStrategist.class));
|
||||||
cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class));
|
cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class));
|
||||||
cards.add(new SetCardInfo("Suki, Kyoshi Warrior", 243, Rarity.UNCOMMON, mage.cards.s.SukiKyoshiWarrior.class));
|
cards.add(new SetCardInfo("Suki, Kyoshi Warrior", 243, Rarity.UNCOMMON, mage.cards.s.SukiKyoshiWarrior.class));
|
||||||
|
cards.add(new SetCardInfo("Swamp", 284, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("The Rise of Sozin", 117, Rarity.MYTHIC, mage.cards.t.TheRiseOfSozin.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("The Rise of Sozin", 356, Rarity.MYTHIC, mage.cards.t.TheRiseOfSozin.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Toph, the Blind Bandit", 198, Rarity.UNCOMMON, mage.cards.t.TophTheBlindBandit.class));
|
cards.add(new SetCardInfo("Toph, the Blind Bandit", 198, Rarity.UNCOMMON, mage.cards.t.TophTheBlindBandit.class));
|
||||||
cards.add(new SetCardInfo("Toph, the First Metalbender", 247, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Toph, the First Metalbender", 247, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS));
|
||||||
|
|
|
||||||
|
|
@ -24,51 +24,85 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet {
|
||||||
super("Avatar: The Last Airbender Eternal", "TLE", ExpansionSet.buildDate(2025, 11, 21), SetType.SUPPLEMENTAL);
|
super("Avatar: The Last Airbender Eternal", "TLE", ExpansionSet.buildDate(2025, 11, 21), SetType.SUPPLEMENTAL);
|
||||||
this.blockName = "Avatar: The Last Airbender"; // for sorting in GUI
|
this.blockName = "Avatar: The Last Airbender"; // for sorting in GUI
|
||||||
this.rotationSet = true;
|
this.rotationSet = true;
|
||||||
this.hasBasicLands = false;
|
this.hasBasicLands = true;
|
||||||
|
|
||||||
cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class));
|
cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class));
|
cards.add(new SetCardInfo("Aang's Defense", 266, Rarity.COMMON, mage.cards.a.AangsDefense.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Aang, Air Nomad", 265, Rarity.RARE, mage.cards.a.AangAirNomad.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Aang, Airbending Master", 74, Rarity.MYTHIC, mage.cards.a.AangAirbendingMaster.class));
|
cards.add(new SetCardInfo("Aang, Airbending Master", 74, Rarity.MYTHIC, mage.cards.a.AangAirbendingMaster.class));
|
||||||
cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class));
|
cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Aardvark Sloth", 267, Rarity.COMMON, mage.cards.a.AardvarkSloth.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class));
|
cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class));
|
||||||
cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class));
|
cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Appa, Aang's Companion", 268, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.class));
|
cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.class));
|
||||||
cards.add(new SetCardInfo("Capital Guard", 234, Rarity.COMMON, mage.cards.c.CapitalGuard.class));
|
cards.add(new SetCardInfo("Capital Guard", 234, Rarity.COMMON, mage.cards.c.CapitalGuard.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Capital Guard", 277, Rarity.COMMON, mage.cards.c.CapitalGuard.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Deny Entry", 222, Rarity.COMMON, mage.cards.d.DenyEntry.class));
|
cards.add(new SetCardInfo("Deny Entry", 222, Rarity.COMMON, mage.cards.d.DenyEntry.class));
|
||||||
cards.add(new SetCardInfo("Dragon Moose", 235, Rarity.COMMON, mage.cards.d.DragonMoose.class));
|
cards.add(new SetCardInfo("Dragon Moose", 235, Rarity.COMMON, mage.cards.d.DragonMoose.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Dragon Moose", 278, Rarity.COMMON, mage.cards.d.DragonMoose.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Earthbending Student", 249, Rarity.UNCOMMON, mage.cards.e.EarthbendingStudent.class));
|
cards.add(new SetCardInfo("Earthbending Student", 249, Rarity.UNCOMMON, mage.cards.e.EarthbendingStudent.class));
|
||||||
cards.add(new SetCardInfo("Eel-Hounds", 250, Rarity.UNCOMMON, mage.cards.e.EelHounds.class));
|
cards.add(new SetCardInfo("Eel-Hounds", 250, Rarity.UNCOMMON, mage.cards.e.EelHounds.class));
|
||||||
cards.add(new SetCardInfo("Elephant-Rat", 228, Rarity.COMMON, mage.cards.e.ElephantRat.class));
|
cards.add(new SetCardInfo("Elephant-Rat", 228, Rarity.COMMON, mage.cards.e.ElephantRat.class));
|
||||||
cards.add(new SetCardInfo("Explore", 259, Rarity.COMMON, mage.cards.e.Explore.class));
|
cards.add(new SetCardInfo("Explore", 259, Rarity.COMMON, mage.cards.e.Explore.class));
|
||||||
cards.add(new SetCardInfo("Explosive Shot", 236, Rarity.COMMON, mage.cards.e.ExplosiveShot.class));
|
cards.add(new SetCardInfo("Explosive Shot", 236, Rarity.COMMON, mage.cards.e.ExplosiveShot.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Explosive Shot", 279, Rarity.COMMON, mage.cards.e.ExplosiveShot.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Feed the Swarm", 257, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class));
|
cards.add(new SetCardInfo("Feed the Swarm", 257, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class));
|
||||||
cards.add(new SetCardInfo("Fire Nation Ambushers", 229, Rarity.COMMON, mage.cards.f.FireNationAmbushers.class));
|
cards.add(new SetCardInfo("Fire Nation Ambushers", 229, Rarity.COMMON, mage.cards.f.FireNationAmbushers.class));
|
||||||
cards.add(new SetCardInfo("Fire Nation Archers", 237, Rarity.RARE, mage.cards.f.FireNationArchers.class));
|
cards.add(new SetCardInfo("Fire Nation Archers", 237, Rarity.RARE, mage.cards.f.FireNationArchers.class));
|
||||||
cards.add(new SetCardInfo("Fire Nation Sentinels", 230, Rarity.RARE, mage.cards.f.FireNationSentinels.class));
|
cards.add(new SetCardInfo("Fire Nation Sentinels", 230, Rarity.RARE, mage.cards.f.FireNationSentinels.class));
|
||||||
cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class));
|
cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class));
|
cards.add(new SetCardInfo("Fire Nation Soldier", 280, Rarity.COMMON, mage.cards.f.FireNationSoldier.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Fire Nation's Conquest", 281, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Flying Dolphin-Fish", 223, Rarity.COMMON, mage.cards.f.FlyingDolphinFish.class));
|
cards.add(new SetCardInfo("Flying Dolphin-Fish", 223, Rarity.COMMON, mage.cards.f.FlyingDolphinFish.class));
|
||||||
cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class));
|
cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class));
|
||||||
cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class));
|
cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class));
|
||||||
cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class));
|
cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class));
|
||||||
cards.add(new SetCardInfo("Hippo-Cows", 252, Rarity.COMMON, mage.cards.h.HippoCows.class));
|
cards.add(new SetCardInfo("Hippo-Cows", 252, Rarity.COMMON, mage.cards.h.HippoCows.class));
|
||||||
cards.add(new SetCardInfo("Iroh, Firebending Instructor", 240, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class));
|
cards.add(new SetCardInfo("Iroh, Firebending Instructor", 240, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Katara, Heroic Healer", 215, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class));
|
cards.add(new SetCardInfo("Iroh, Firebending Instructor", 282, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Katara, Heroic Healer", 215, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Katara, Heroic Healer", 269, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class));
|
cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class));
|
||||||
cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class));
|
cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Komodo Rhino", 283, Rarity.COMMON, mage.cards.k.KomodoRhino.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class));
|
cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class));
|
||||||
cards.add(new SetCardInfo("Lion Vulture", 232, Rarity.RARE, mage.cards.l.LionVulture.class));
|
cards.add(new SetCardInfo("Lion Vulture", 232, Rarity.RARE, mage.cards.l.LionVulture.class));
|
||||||
cards.add(new SetCardInfo("Lost in the Spirit World", 224, Rarity.UNCOMMON, mage.cards.l.LostInTheSpiritWorld.class));
|
cards.add(new SetCardInfo("Lost in the Spirit World", 224, Rarity.UNCOMMON, mage.cards.l.LostInTheSpiritWorld.class));
|
||||||
cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class));
|
cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class));
|
||||||
cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class));
|
cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class));
|
||||||
cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class));
|
cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class));
|
||||||
cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 217, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class));
|
cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 217, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 270, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 289, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 291, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 292, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 293, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 294, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 295, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Mountain", 296, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Path to Redemption", 271, Rarity.COMMON, mage.cards.p.PathToRedemption.class));
|
||||||
|
cards.add(new SetCardInfo("Plains", 297, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 298, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 299, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 300, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 301, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 302, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 303, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Plains", 304, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class));
|
cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class));
|
||||||
|
cards.add(new SetCardInfo("Razor Rings", 272, Rarity.COMMON, mage.cards.r.RazorRings.class));
|
||||||
cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class));
|
cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class));
|
||||||
cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class));
|
cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Run Amok", 284, Rarity.COMMON, mage.cards.r.RunAmok.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Seismic Tutelage", 254, Rarity.RARE, mage.cards.s.SeismicTutelage.class));
|
cards.add(new SetCardInfo("Seismic Tutelage", 254, Rarity.RARE, mage.cards.s.SeismicTutelage.class));
|
||||||
cards.add(new SetCardInfo("Sledding Otter-Penguin", 218, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class));
|
cards.add(new SetCardInfo("Sledding Otter-Penguin", 218, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Sokka, Wolf Cove's Protector", 219, Rarity.UNCOMMON, mage.cards.s.SokkaWolfCovesProtector.class));
|
cards.add(new SetCardInfo("Sledding Otter-Penguin", 273, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Sokka, Wolf Cove's Protector", 219, Rarity.UNCOMMON, mage.cards.s.SokkaWolfCovesProtector.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Sokka, Wolf Cove's Protector", 274, Rarity.UNCOMMON, mage.cards.s.SokkaWolfCovesProtector.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class));
|
cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class));
|
||||||
cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class));
|
cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class));
|
||||||
cards.add(new SetCardInfo("The Terror of Serpent's Pass", 225, Rarity.RARE, mage.cards.t.TheTerrorOfSerpentsPass.class));
|
cards.add(new SetCardInfo("The Terror of Serpent's Pass", 225, Rarity.RARE, mage.cards.t.TheTerrorOfSerpentsPass.class));
|
||||||
|
|
@ -77,14 +111,20 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class));
|
cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class));
|
||||||
cards.add(new SetCardInfo("Thriving Isle", 263, Rarity.COMMON, mage.cards.t.ThrivingIsle.class));
|
cards.add(new SetCardInfo("Thriving Isle", 263, Rarity.COMMON, mage.cards.t.ThrivingIsle.class));
|
||||||
cards.add(new SetCardInfo("Thriving Moor", 264, Rarity.COMMON, mage.cards.t.ThrivingMoor.class));
|
cards.add(new SetCardInfo("Thriving Moor", 264, Rarity.COMMON, mage.cards.t.ThrivingMoor.class));
|
||||||
cards.add(new SetCardInfo("Tundra Wall", 220, Rarity.COMMON, mage.cards.t.TundraWall.class));
|
cards.add(new SetCardInfo("Tundra Wall", 220, Rarity.COMMON, mage.cards.t.TundraWall.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Tundra Wall", 275, Rarity.COMMON, mage.cards.t.TundraWall.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Turtle-Seals", 226, Rarity.COMMON, mage.cards.t.TurtleSeals.class));
|
cards.add(new SetCardInfo("Turtle-Seals", 226, Rarity.COMMON, mage.cards.t.TurtleSeals.class));
|
||||||
cards.add(new SetCardInfo("Warship Scout", 244, Rarity.COMMON, mage.cards.w.WarshipScout.class));
|
cards.add(new SetCardInfo("Warship Scout", 244, Rarity.COMMON, mage.cards.w.WarshipScout.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Warship Scout", 285, Rarity.COMMON, mage.cards.w.WarshipScout.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Water Whip", 227, Rarity.RARE, mage.cards.w.WaterWhip.class));
|
cards.add(new SetCardInfo("Water Whip", 227, Rarity.RARE, mage.cards.w.WaterWhip.class));
|
||||||
cards.add(new SetCardInfo("Wolf Cove Villager", 221, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class));
|
cards.add(new SetCardInfo("Wolf Cove Villager", 221, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class));
|
cards.add(new SetCardInfo("Wolf Cove Villager", 276, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Zuko's Offense", 247, Rarity.COMMON, mage.cards.z.ZukosOffense.class));
|
cards.add(new SetCardInfo("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Zuko, Avatar Hunter", 246, Rarity.RARE, mage.cards.z.ZukoAvatarHunter.class));
|
cards.add(new SetCardInfo("Zhao, the Seething Flame", 286, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Zuko's Offense", 247, Rarity.COMMON, mage.cards.z.ZukosOffense.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Zuko's Offense", 288, Rarity.COMMON, mage.cards.z.ZukosOffense.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Zuko, Avatar Hunter", 246, Rarity.RARE, mage.cards.z.ZukoAvatarHunter.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Zuko, Avatar Hunter", 287, Rarity.RARE, mage.cards.z.ZukoAvatarHunter.class, NON_FULL_USE_VARIOUS));
|
||||||
|
|
||||||
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.mage.test.cards.continuous;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class AddCardSubtypeAllEffectTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Kudo, King Among Bears
|
||||||
|
{G}{W}
|
||||||
|
Legendary Creature — Bear
|
||||||
|
Other creatures have base power and toughness 2/2 and are Bears in addition to their other types.
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String kudo = "Kudo, King Among Bears";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fugitive Wizard
|
||||||
|
{U}
|
||||||
|
Creature — Human Wizard
|
||||||
|
1/1
|
||||||
|
*/
|
||||||
|
private static final String fugitive = "Fugitive Wizard";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddCardSubtypeAllEffect() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, fugitive, 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, fugitive, 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, kudo);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Savannah", 2);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) {
|
||||||
|
if (permanent.getName().equals(fugitive)) {
|
||||||
|
assertTrue(permanent.hasSubtype(SubType.BEAR, currentGame));
|
||||||
|
assertTrue(permanent.hasSubtype(SubType.WIZARD, currentGame));
|
||||||
|
assertTrue(permanent.hasSubtype(SubType.HUMAN, currentGame));
|
||||||
|
assertEquals(2, permanent.getPower().getModifiedBaseValue());
|
||||||
|
assertEquals(2, permanent.getToughness().getModifiedBaseValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSubtype(kudo, SubType.BEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package org.mage.test.cards.continuous;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class BecomesColorEffectTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ancient Kavu
|
||||||
|
{3}{R}
|
||||||
|
Creature — Kavu
|
||||||
|
{2}: This creature becomes colorless until end of turn.
|
||||||
|
Those with the ability to change their nature survived Phyrexia’s biological attacks. Everything else died.
|
||||||
|
3/3
|
||||||
|
*/
|
||||||
|
String kavu = "Ancient Kavu";
|
||||||
|
/*
|
||||||
|
Alchor's Tomb
|
||||||
|
{4}
|
||||||
|
Artifact
|
||||||
|
{2}, {T}: Target permanent you control becomes the color of your choice. (This effect lasts indefinitely.)
|
||||||
|
*/
|
||||||
|
String alchorsTomb = "Alchor's Tomb";
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBecomesColorSource() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, kavu);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
|
||||||
|
checkColor("Ancient Kavu is red", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}: {this}");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
checkColor("Ancient Kavu is colorless", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "C", true);
|
||||||
|
checkColor("Ancient Kavu is red again", 2, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||||
|
|
||||||
|
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBecomesColorTarget() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, kavu);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, alchorsTomb);
|
||||||
|
|
||||||
|
checkColor("Ancient Kavu is red", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||||
|
// make Ancient Kavu green
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Target permanent", kavu);
|
||||||
|
setChoice(playerA, "Green");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
checkColor("Ancient Kavu is green", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||||
|
checkColor("Ancient Kavu is still green the following turn", 2, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||||
|
// activate Ancient Kavu's ability to override green color until end of turn
|
||||||
|
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}: {this}");
|
||||||
|
checkColor("Ancient Kavu is colorless", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, kavu, "C", true);
|
||||||
|
// next turn it should be green again
|
||||||
|
checkColor("Ancient Kavu is green again", 4, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||||
|
|
||||||
|
setStopAt(4, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.mage.test.cards.continuous;
|
||||||
|
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||||
|
import mage.filter.predicate.mageobject.ToughnessPredicate;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class BecomesCreatureEffectTest extends CardTestPlayerBase {
|
||||||
|
/*
|
||||||
|
Ambush Commander
|
||||||
|
{3}{G}{G}
|
||||||
|
Creature — Elf
|
||||||
|
Forests you control are 1/1 green Elf creatures that are still lands.
|
||||||
|
{1}{G}, Sacrifice an Elf: Target creature gets +3/+3 until end of turn.
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
String ambushCommander = "Ambush Commander";
|
||||||
|
/*
|
||||||
|
Dryad Arbor
|
||||||
|
Land Creature — Forest Dryad
|
||||||
|
1/1
|
||||||
|
*/
|
||||||
|
String dryadArbor = "Dryad Arbor";
|
||||||
|
/*
|
||||||
|
Frogify
|
||||||
|
{1}{U}
|
||||||
|
Enchantment — Aura
|
||||||
|
Enchant creature
|
||||||
|
Enchanted creature loses all abilities and is a blue Frog creature with base power and toughness 1/1.
|
||||||
|
(It loses all other card types and creature types.)
|
||||||
|
*/
|
||||||
|
String frogify = "Frogify";
|
||||||
|
@Test
|
||||||
|
public void testBecomesCreatureAllEffect() {
|
||||||
|
FilterPermanent filter = new FilterPermanent();
|
||||||
|
filter.add(CardType.CREATURE.getPredicate());
|
||||||
|
filter.add(SubType.ELF.getPredicate());
|
||||||
|
filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, 1));
|
||||||
|
filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, 1));
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, dryadArbor);
|
||||||
|
addCard(Zone.HAND, playerA, ambushCommander);
|
||||||
|
|
||||||
|
runCode("Check forests are not 1/1 Elves", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||||
|
int numElves = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size();
|
||||||
|
Assert.assertEquals("No 1/1 elves should be present", 0, numElves);
|
||||||
|
});
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ambushCommander);
|
||||||
|
runCode("Check forests are 1/1 Elves", 1, PhaseStep.BEGIN_COMBAT, playerA, (info, player, game) -> {
|
||||||
|
int numElves = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size();
|
||||||
|
// 5 forests + dryad arbor
|
||||||
|
Assert.assertEquals("There should be 6 1/1 elves present", 6, numElves);
|
||||||
|
});
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBecomesCreatureAttachedEffect() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, dryadArbor);
|
||||||
|
addCard(Zone.HAND, playerA, frogify);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, frogify, dryadArbor);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAbilities(playerA, dryadArbor, Collections.emptyList());
|
||||||
|
assertPowerToughness(playerA, dryadArbor, 1, 1);
|
||||||
|
assertType(dryadArbor, CardType.CREATURE, SubType.FROG);
|
||||||
|
assertNotSubtype(dryadArbor, SubType.DRYAD);
|
||||||
|
assertNotType(dryadArbor, CardType.LAND);
|
||||||
|
assertColor(playerA, dryadArbor, ObjectColor.BLUE, true);
|
||||||
|
assertColor(playerA, dryadArbor, ObjectColor.GREEN, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.mage.test.cards.continuous;
|
||||||
|
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class BecomesCreatureIfVehicleEffectTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aerial Modification
|
||||||
|
{4}{W}
|
||||||
|
Enchantment — Aura
|
||||||
|
Enchant creature or Vehicle
|
||||||
|
As long as enchanted permanent is a Vehicle, it’s a creature in addition to its other types.
|
||||||
|
Enchanted creature gets +2/+2 and has flying.
|
||||||
|
*/
|
||||||
|
String aerialMod = "Aerial Modification";
|
||||||
|
/*
|
||||||
|
Goliath Truck
|
||||||
|
{4}
|
||||||
|
Artifact — Vehicle
|
||||||
|
Stowage — Whenever this Vehicle attacks, put two +1/+1 counters on another target attacking creature.
|
||||||
|
Crew 2 (Tap any number of creatures you control with total power 2 or more: This Vehicle becomes an artifact creature until end of turn.)
|
||||||
|
4/4
|
||||||
|
*/
|
||||||
|
String goliathTruck = "Goliath Truck";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBecomesCreatureIfVehicleEffect() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, goliathTruck);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||||
|
addCard(Zone.HAND, playerA, aerialMod);
|
||||||
|
|
||||||
|
checkType("Goliath Truck is not a creature", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goliathTruck, CardType.CREATURE, false);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aerialMod, goliathTruck);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertType(goliathTruck, CardType.CREATURE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -157,4 +157,29 @@ public class EmblemsTest extends CardTestPlayerBase {
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJayaFieryNegotiator() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Jaya, Fiery Negotiator");
|
||||||
|
addCard(Zone.HAND, playerA, "Wrenn's Resolve");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||||
|
addCard(Zone.LIBRARY, playerA, "Lightning Bolt", 2);
|
||||||
|
skipInitShuffling();
|
||||||
|
|
||||||
|
addCounters(1, PhaseStep.UPKEEP, playerA, "Jaya, Fiery Negotiator", CounterType.LOYALTY, 6);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-8: You get an emblem");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wrenn's Resolve");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||||
|
setChoice(playerA, false, 2);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertExileCount(playerA, 6 - 1);
|
||||||
|
assertLife(playerB, 20 - 3 * 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.mage.test.cards.single._5ed;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AnHavvaConstableTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
An-Havva Constable
|
||||||
|
{1}{G}{G}
|
||||||
|
Creature — Human
|
||||||
|
An-Havva Constable’s toughness is equal to 1 plus the number of green creatures on the battlefield.
|
||||||
|
2/1+*
|
||||||
|
*/
|
||||||
|
private static final String constable = "An-Havva Constable";
|
||||||
|
/*
|
||||||
|
Bear Cub
|
||||||
|
{1}{G}
|
||||||
|
Creature — Bear
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String cub = "Bear Cub";
|
||||||
|
@Test
|
||||||
|
public void testAnHavva() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, constable);
|
||||||
|
addCard(Zone.HAND, playerA, constable);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, cub, 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, cub, 3);
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
|
||||||
|
checkPT("An-Havva Constable has toughness 7", 1, PhaseStep.PRECOMBAT_MAIN, playerA, constable, 2, 1 + 6);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", cub);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
checkPT("An-Havva Constable has toughness 6", 1, PhaseStep.PRECOMBAT_MAIN, playerA, constable, 2, 1 + 5);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
playerA.getHand().getCards(currentGame).stream()
|
||||||
|
.filter(card -> card.getName().equals(constable))
|
||||||
|
.findFirst().
|
||||||
|
ifPresent(card -> Assert.assertEquals(6, card.getToughness().getValue()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package org.mage.test.cards.single.avr;
|
||||||
|
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class DarkImpostorTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dark Impostor
|
||||||
|
{2}{B}
|
||||||
|
Creature — Vampire Assassin
|
||||||
|
|
||||||
|
{4}{B}{B}: Exile target creature and put a +1/+1 counter on this creature.
|
||||||
|
|
||||||
|
This creature has all activated abilities of all creature cards exiled with it.
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
public static final String darkImposter = "Dark Impostor";
|
||||||
|
/*
|
||||||
|
Deathrite Shaman
|
||||||
|
{B/G}
|
||||||
|
Creature — Elf Shaman
|
||||||
|
|
||||||
|
{T}: Exile target land card from a graveyard. Add one mana of any color.
|
||||||
|
|
||||||
|
{B}, {T}: Exile target instant or sorcery card from a graveyard. Each opponent loses 2 life.
|
||||||
|
|
||||||
|
{G}, {T}: Exile target creature card from a graveyard. You gain 2 life.
|
||||||
|
|
||||||
|
1/2
|
||||||
|
*/
|
||||||
|
public static final String deathriteShaman = "Deathrite Shaman";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDarkImpostor() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, darkImposter);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, deathriteShaman);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{B}{B}");
|
||||||
|
addTarget(playerA, deathriteShaman);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAbilityCount(playerA, darkImposter, SimpleActivatedAbility.class, 4); // own ability + 3 other from deathrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.mage.test.cards.single.c13;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class ActOfAuthorityEffectTest extends CardTestPlayerBase {
|
||||||
|
/*
|
||||||
|
Act of Authority
|
||||||
|
{1}{W}{W}
|
||||||
|
Enchantment
|
||||||
|
When this enchantment enters, you may exile target artifact or enchantment.
|
||||||
|
At the beginning of your upkeep, you may exile target artifact or enchantment. If you do, its controller gains control of this enchantment.
|
||||||
|
*/
|
||||||
|
private static final String actOfAuthority = "Act of Authority";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testActOfAuthority() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, actOfAuthority);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, actOfAuthority + "@actB");
|
||||||
|
|
||||||
|
setChoice(playerA, true); // upkeep
|
||||||
|
addTarget(playerA, "@actB");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerB, actOfAuthority, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.mage.test.cards.single.dft;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AatchikEmeraldRadianTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aatchik, Emerald Radian
|
||||||
|
{3}{B}{B}{G}
|
||||||
|
Legendary Creature — Insect Druid
|
||||||
|
When Aatchik enters, create a 1/1 green Insect creature token for each artifact and/or creature card in your graveyard.
|
||||||
|
Whenever another Insect you control dies, put a +1/+1 counter on Aatchik. Each opponent loses 1 life.
|
||||||
|
3/3
|
||||||
|
*/
|
||||||
|
private static final String aatchik = "Aatchik, Emerald Radian";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Springheart Nantuko
|
||||||
|
{1}{G}
|
||||||
|
Enchantment Creature — Insect Monk
|
||||||
|
Bestow {1}{G}
|
||||||
|
Enchanted creature gets +1/+1.
|
||||||
|
Landfall — Whenever a land you control enters, you may pay {1}{G} if this permanent is attached to a creature you control.
|
||||||
|
If you do, create a token that’s a copy of that creature. If you didn’t create a token this way, create a 1/1 green Insect creature token.
|
||||||
|
1/1
|
||||||
|
*/
|
||||||
|
private static final String nantuko = "Springheart Nantuko";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpponentCreatingTokens() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, aatchik);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, aatchik);
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, aatchik);
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, aatchik);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Bayou", 9);
|
||||||
|
addCard(Zone.HAND, playerA, nantuko);
|
||||||
|
addCard(Zone.HAND, playerA, "Bayou");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nantuko + " using bestow");
|
||||||
|
addTarget(playerA, aatchik);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bayou");
|
||||||
|
setChoice(playerA, true);
|
||||||
|
setChoice(playerA, aatchik);
|
||||||
|
setChoice(playerA, "When {this} enters");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertTokenCount(playerB, "Insect Token", 0);
|
||||||
|
assertTokenCount(playerA, "Insect Token", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.mage.test.cards.single.dis;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.UntapAllControllerEffect;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ExperimentKrajTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Experiment Kraj
|
||||||
|
{2}{G}{G}{U}{U}
|
||||||
|
Legendary Creature — Ooze Mutant
|
||||||
|
|
||||||
|
Experiment Kraj has all activated abilities of each other creature with a +1/+1 counter on it.
|
||||||
|
|
||||||
|
{T}: Put a +1/+1 counter on target creature.
|
||||||
|
*/
|
||||||
|
private static final String experimentKraj = "Experiment Kraj";
|
||||||
|
/*
|
||||||
|
Stoneforge Mystic
|
||||||
|
{1}{W}
|
||||||
|
Creature — Kor Artificer
|
||||||
|
|
||||||
|
When this creature enters, you may search your library for an Equipment card, reveal it, put it into your hand, then shuffle.
|
||||||
|
|
||||||
|
{1}{W}, {T}: You may put an Equipment card from your hand onto the battlefield.
|
||||||
|
*/
|
||||||
|
private static final String stoneforgeMystic = "Stoneforge Mystic";
|
||||||
|
/*
|
||||||
|
Noble Hierarch
|
||||||
|
{G}
|
||||||
|
Creature — Human Druid
|
||||||
|
|
||||||
|
Exalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.)
|
||||||
|
|
||||||
|
{T}: Add {G}, {W}, or {U}.
|
||||||
|
*/
|
||||||
|
private static final String nobleHierarch = "Noble Hierarch";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExperimentKraj() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
Ability ability = new SimpleActivatedAbility(
|
||||||
|
Zone.ALL,
|
||||||
|
new UntapAllControllerEffect(StaticFilters.FILTER_CONTROLLED_A_CREATURE),
|
||||||
|
new ManaCostsImpl<>("")
|
||||||
|
);
|
||||||
|
addCustomCardWithAbility("Untap creatures", playerA, ability);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, experimentKraj);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, stoneforgeMystic);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, nobleHierarch);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Put a +1/+1", stoneforgeMystic);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Put a +1/+1", nobleHierarch);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertEquals("Kraj should have 5 activated abilities", 5, getPermanent(experimentKraj).getAbilities(currentGame)
|
||||||
|
.stream()
|
||||||
|
.filter(Ability::isActivatedAbility)
|
||||||
|
.count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.mage.test.cards.single.fic;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.UntapAllControllerEffect;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
public class UriangerAugureltTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
private static final String urianger = "Urianger Augurelt";
|
||||||
|
private static final String arcaneSignet = "Arcane Signet";
|
||||||
|
private static final String howlingMine = "Howling Mine";
|
||||||
|
private static final String thoughtVessel = "Thought Vessel";
|
||||||
|
private static final String benalishKnight = "Benalish Knight";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriangerAugureltTest() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
skipInitShuffling();
|
||||||
|
removeAllCardsFromLibrary(playerA);
|
||||||
|
|
||||||
|
Ability ability = new SimpleActivatedAbility(
|
||||||
|
Zone.ALL,
|
||||||
|
new UntapAllControllerEffect(StaticFilters.FILTER_CONTROLLED_A_CREATURE),
|
||||||
|
new ManaCostsImpl<>("")
|
||||||
|
);
|
||||||
|
addCustomCardWithAbility("Untap creatures", playerA, ability);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, urianger);
|
||||||
|
addCard(Zone.LIBRARY, playerA, "Plains", 3);
|
||||||
|
addCard(Zone.LIBRARY, playerA, arcaneSignet);
|
||||||
|
addCard(Zone.LIBRARY, playerA, howlingMine);
|
||||||
|
addCard(Zone.LIBRARY, playerA, thoughtVessel);
|
||||||
|
addCard(Zone.LIBRARY, playerA, benalishKnight);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||||
|
setChoice(playerA, true, 4);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||||
|
|
||||||
|
|
||||||
|
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Play Arcanum</i>");
|
||||||
|
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains");
|
||||||
|
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, benalishKnight, true);
|
||||||
|
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, arcaneSignet, true);
|
||||||
|
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, howlingMine, true);
|
||||||
|
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, thoughtVessel, true);
|
||||||
|
|
||||||
|
setStopAt(3, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, benalishKnight, 1);
|
||||||
|
assertPermanentCount(playerA, arcaneSignet, 1);
|
||||||
|
assertPermanentCount(playerA, howlingMine, 1);
|
||||||
|
assertPermanentCount(playerA, thoughtVessel, 1);
|
||||||
|
assertLife(playerA, 20 + 2 * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.mage.test.cards.single.fin;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AettirAndPriwenTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aettir and Priwen
|
||||||
|
{6}
|
||||||
|
Legendary Artifact — Equipment
|
||||||
|
Equipped creature has base power and toughness X/X, where X is your life total.
|
||||||
|
Equip {5}
|
||||||
|
*/
|
||||||
|
private static final String aettir = "Aettir and Priwen";
|
||||||
|
/*
|
||||||
|
Bear Cub
|
||||||
|
{1}{G}
|
||||||
|
Creature — Bear
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String cub = "Bear Cub";
|
||||||
|
/*
|
||||||
|
Lightning Bolt
|
||||||
|
{R}
|
||||||
|
Instant
|
||||||
|
Lightning Bolt deals 3 damage to any target.
|
||||||
|
*/
|
||||||
|
public static final String bolt = "Lightning Bolt";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAettirAndPriwen() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, aettir);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 7);
|
||||||
|
addCard(Zone.HAND, playerA, bolt, 2);
|
||||||
|
|
||||||
|
checkPowerToughness(2, cub, 1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{5}: Equip");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
checkPowerToughness(20, cub, 1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bolt, playerA);
|
||||||
|
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
checkPowerToughness(20 - 3, cub, 1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bolt, playerA);
|
||||||
|
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
checkPowerToughness(20 - 3 * 2, cub, 1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
|
||||||
|
checkPowerToughness(20 - 3 * 2, cub, 2, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkPowerToughness(int xValue, String name, int turnNum, PhaseStep phaseStep) {
|
||||||
|
runCode("Checking P/T is " + xValue, turnNum, phaseStep, playerA, (info, player, game) -> {
|
||||||
|
Permanent permanent = getPermanent(name, player);
|
||||||
|
Assert.assertEquals(xValue, permanent.getPower().getModifiedBaseValue());
|
||||||
|
Assert.assertEquals(xValue, permanent.getToughness().getModifiedBaseValue());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.mage.test.cards.single.lci;
|
||||||
|
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AbuelosAwakeningTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Abuelo's Awakening
|
||||||
|
{X}{3}{W}
|
||||||
|
Sorcery
|
||||||
|
Return target artifact or non-Aura enchantment card from your graveyard to the battlefield with X additional +1/+1 counters on it.
|
||||||
|
It’s a 1/1 Spirit creature with flying in addition to its other types.
|
||||||
|
*/
|
||||||
|
public static final String abuelosAwakening = "Abuelo's Awakening";
|
||||||
|
/*
|
||||||
|
Talisman of Progress
|
||||||
|
{2}
|
||||||
|
Artifact
|
||||||
|
{T}: Add {C}.
|
||||||
|
{T}: Add {W} or {U}. This artifact deals 1 damage to you.
|
||||||
|
*/
|
||||||
|
public static final String talisman = "Talisman of Progress";
|
||||||
|
/*
|
||||||
|
Lightning Bolt
|
||||||
|
{R}
|
||||||
|
Instant
|
||||||
|
Lightning Bolt deals 3 damage to any target.
|
||||||
|
*/
|
||||||
|
public static final String bolt = "Lightning Bolt";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbuelosAwakening() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, talisman);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||||
|
addCard(Zone.HAND, playerA, abuelosAwakening);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, abuelosAwakening, talisman);
|
||||||
|
setChoiceAmount(playerA, 2);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertCounterCount(playerA, talisman, CounterType.P1P1, 2);
|
||||||
|
assertType(talisman, CardType.CREATURE, true);
|
||||||
|
assertSubtype(talisman, SubType.SPIRIT);
|
||||||
|
assertBasePowerToughness(playerA, talisman, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbuelosAwakeningDies() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, talisman);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||||
|
addCard(Zone.HAND, playerA, abuelosAwakening);
|
||||||
|
addCard(Zone.HAND, playerB, bolt);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, abuelosAwakening, talisman);
|
||||||
|
setChoiceAmount(playerA, 2);
|
||||||
|
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, bolt, talisman);
|
||||||
|
|
||||||
|
setStopAt(2, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, talisman, 0);
|
||||||
|
assertGraveyardCount(playerA, talisman, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.mage.test.cards.single.lci;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
public class DireBlunderbussTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dire Blunderbuss
|
||||||
|
Color Indicator: RedArtifact — Equipment
|
||||||
|
|
||||||
|
Equipped creature gets +3/+0 and has “Whenever this creature attacks, you may sacrifice an artifact other than Dire Blunderbuss. When you do, this creature deals damage equal to its power to target creature.”
|
||||||
|
|
||||||
|
Equip {1}
|
||||||
|
*/
|
||||||
|
private static final String direBlunderBuss = "Dire Blunderbuss";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void DireBlunderbussTest() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, direBlunderBuss);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears@bearsB");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Tormod's Crypt");
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears");
|
||||||
|
|
||||||
|
attack(1, playerA, "Balduvian Bears");
|
||||||
|
setChoice(playerA, true);
|
||||||
|
setChoice(playerA, "Tormod's Crypt");
|
||||||
|
addTarget(playerA, "@bearsB");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, "Balduvian Bears", 1);
|
||||||
|
assertLife(playerB, 20 - 2 - 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.mage.test.cards.single.lci;
|
||||||
|
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
public class EatenByPiranhasTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eaten by Piranhas
|
||||||
|
{1}{U}
|
||||||
|
Enchantment — Aura
|
||||||
|
|
||||||
|
Flash (You may cast this spell any time you could cast an instant.)
|
||||||
|
|
||||||
|
Enchant creature
|
||||||
|
|
||||||
|
Enchanted creature loses all abilities and is a black Skeleton creature with base power and toughness 1/1. (It loses all other colors, card types, and creature types.)
|
||||||
|
*/
|
||||||
|
private static final String eatenByPiranhas = "Eaten by Piranhas";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEatenByPiranhas() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.HAND, playerB, eatenByPiranhas);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, eatenByPiranhas);
|
||||||
|
addTarget(playerB, "Balduvian Bears");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertType("Balduvian Bears", CardType.CREATURE, SubType.SKELETON);
|
||||||
|
assertPowerToughness(playerA, "Balduvian Bears", 1, 1);
|
||||||
|
assertColor(playerA, "Balduvian Bears", ObjectColor.BLACK, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package org.mage.test.cards.single.m19;
|
||||||
|
|
||||||
|
import mage.abilities.mana.AnyColorManaAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AlpineMoonTest extends CardTestPlayerBase {
|
||||||
|
/*
|
||||||
|
Alpine Moon
|
||||||
|
{R}
|
||||||
|
Enchantment
|
||||||
|
As this enchantment enters, choose a nonbasic land card name.
|
||||||
|
Lands your opponents control with the chosen name lose all land types and abilities, and they gain “{T}: Add one mana of any color.”
|
||||||
|
*/
|
||||||
|
private static final String alpine = "Alpine Moon";
|
||||||
|
/*
|
||||||
|
Urborg, Tomb of Yawgmoth
|
||||||
|
Legendary Land
|
||||||
|
Each land is a Swamp in addition to its other land types.
|
||||||
|
*/
|
||||||
|
private static final String urborg = "Urborg, Tomb of Yawgmoth";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlpineMoonAfterUrborg() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, urborg);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, alpine);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
|
||||||
|
setChoice(playerB, urborg);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertNotSubtype(urborg, SubType.SWAMP);
|
||||||
|
assertSubtype("Mountain", SubType.SWAMP);
|
||||||
|
assertSubtype("Island", SubType.SWAMP);
|
||||||
|
assertAbility(playerA, urborg, new AnyColorManaAbility(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlpineMoonBeforeUrborg() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, urborg);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, alpine);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||||
|
|
||||||
|
setChoice(playerA, urborg);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertNotSubtype(urborg, SubType.SWAMP);
|
||||||
|
assertSubtype("Mountain", SubType.SWAMP);
|
||||||
|
assertSubtype("Island", SubType.SWAMP);
|
||||||
|
assertAbility(playerB, urborg, new AnyColorManaAbility(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
package org.mage.test.cards.single.mh2;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.permanent.PermanentToken;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AeveProgenitorOozeTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aeve, Progenitor Ooze
|
||||||
|
{2}{G}{G}{G}
|
||||||
|
Legendary Creature — Ooze
|
||||||
|
Storm (When you cast this spell, copy it for each spell cast before it this turn. Copies become tokens.)
|
||||||
|
Aeve isn’t legendary if it’s a token.
|
||||||
|
Aeve enters with a +1/+1 counter on it for each other Ooze you control.
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String aeve = "Aeve, Progenitor Ooze";
|
||||||
|
/*
|
||||||
|
Lightning Bolt
|
||||||
|
{R}
|
||||||
|
Instant
|
||||||
|
Lightning Bolt deals 3 damage to any target.
|
||||||
|
*/
|
||||||
|
public static final String bolt = "Lightning Bolt";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAeve() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.HAND, playerA, aeve);
|
||||||
|
addCard(Zone.HAND, playerA, bolt);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerB);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aeve);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, aeve, 2);
|
||||||
|
assertTokenCount(playerA, aeve, 1);
|
||||||
|
for (Permanent permanent : currentGame.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerA.getId(), currentGame)) {
|
||||||
|
if (permanent.getName().equals(aeve)) {
|
||||||
|
if (permanent instanceof PermanentToken) {
|
||||||
|
Assert.assertEquals(0, permanent.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||||
|
} else {
|
||||||
|
Assert.assertEquals(1, permanent.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package org.mage.test.cards.single.mir;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.player.TestPlayer;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class PhyrexianDreadnoughtTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Phyrexian Dreadnought
|
||||||
|
{1}
|
||||||
|
Artifact Creature — Phyrexian Dreadnought
|
||||||
|
|
||||||
|
Trample
|
||||||
|
|
||||||
|
When this creature enters, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater.
|
||||||
|
|
||||||
|
12/12
|
||||||
|
*/
|
||||||
|
private static final String phyrexianDreadnought = "Phyrexian Dreadnought";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPhyrexianDreadnoughtCanPay() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.HAND, playerA, phyrexianDreadnought);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, phyrexianDreadnought + "@sacTarget");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, phyrexianDreadnought);
|
||||||
|
setChoice(playerA, true);
|
||||||
|
setChoice(playerA, "@sacTarget");
|
||||||
|
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, phyrexianDreadnought, 1);
|
||||||
|
assertGraveyardCount(playerA, phyrexianDreadnought, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPhyrexianDreadnoughtCantPay() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.HAND, playerA, phyrexianDreadnought);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, phyrexianDreadnought);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setChoice(playerA, false);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, phyrexianDreadnought, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package org.mage.test.cards.single.neo;
|
||||||
|
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.HasteAbility;
|
||||||
|
import mage.abilities.keyword.LifelinkAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
public class EaterOfVirtueTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eater of Virtue
|
||||||
|
{1}
|
||||||
|
Legendary Artifact — Equipment
|
||||||
|
|
||||||
|
Whenever equipped creature dies, exile it.
|
||||||
|
|
||||||
|
Equipped creature gets +2/+0.
|
||||||
|
|
||||||
|
As long as a card exiled with Eater of Virtue has flying, equipped creature has flying.
|
||||||
|
The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance.
|
||||||
|
|
||||||
|
Equip {1}
|
||||||
|
*/
|
||||||
|
public static final String eaterOfVirtue = "Eater of Virtue";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEaterOfVirtue() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, eaterOfVirtue);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Adult Gold Dragon"); // Flying, Lifelink, Haste
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||||
|
addCard(Zone.HAND, playerB, "Doom Blade");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Adult Gold Dragon");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Doom Blade", "Adult Gold Dragon");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||||
|
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Equip", "Balduvian Bears");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAbilities(playerA, "Balduvian Bears", Arrays.asList(FlyingAbility.getInstance(), LifelinkAbility.getInstance(), HasteAbility.getInstance()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.mage.test.cards.single.one;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
public class EncroachingMycosynthTest extends CardTestCommanderDuelBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Encroaching Mycosynth
|
||||||
|
{3}{U}
|
||||||
|
Artifact
|
||||||
|
|
||||||
|
Nonland permanents you control are artifacts in addition to their other types.
|
||||||
|
The same is true for permanent spells you control and nonland permanent cards you own that aren’t on the battlefield.
|
||||||
|
*/
|
||||||
|
private static final String encroachingMycosynth = "Encroaching Mycosynth";
|
||||||
|
private static final String balduvianBears = "Balduvian Bears";
|
||||||
|
@Test
|
||||||
|
public void testEncroachingMycosynth() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, balduvianBears);
|
||||||
|
addCard(Zone.HAND, playerA, balduvianBears, 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, encroachingMycosynth);
|
||||||
|
addCard(Zone.EXILED, playerA, balduvianBears);
|
||||||
|
addCard(Zone.LIBRARY, playerA, balduvianBears);
|
||||||
|
addCard(Zone.COMMAND, playerA, balduvianBears);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, balduvianBears);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertType(balduvianBears, CardType.ARTIFACT, true);
|
||||||
|
List<Card> cards = getHandCards(playerA);
|
||||||
|
cards.addAll(getLibraryCards(playerA));
|
||||||
|
cards.addAll(getCommandCards(playerA));
|
||||||
|
cards.addAll(getExiledCards(playerA));
|
||||||
|
cards.addAll(getLibraryCards(playerA));
|
||||||
|
for (Card card : cards) {
|
||||||
|
if (!card.isLand(currentGame)) {
|
||||||
|
assertTrue(card.getCardType(currentGame).contains(CardType.ARTIFACT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package org.mage.test.cards.single.one;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
public class NahirisSacrificeTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nahiri's Sacrifice
|
||||||
|
{1}{R}
|
||||||
|
Sorcery
|
||||||
|
|
||||||
|
As an additional cost to cast this spell, sacrifice an artifact or creature with mana value X.
|
||||||
|
|
||||||
|
Nahiri’s Sacrifice deals X damage divided as you choose among any number of target creatures.
|
||||||
|
*/
|
||||||
|
private static final String nahirisSacrifice = "Nahiri's Sacrifice";
|
||||||
|
private static final String balduvianBears = "Balduvian Bears";
|
||||||
|
@Test
|
||||||
|
public void testNahirisSacrifice() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.HAND, playerA, nahirisSacrifice);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, balduvianBears + "@bearsB");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nahirisSacrifice, "@bearsB");
|
||||||
|
setChoice(playerA, "X=2");
|
||||||
|
setChoice(playerA, balduvianBears);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, balduvianBears, 1);
|
||||||
|
assertGraveyardCount(playerA, nahirisSacrifice, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore // Enable after merging #13916
|
||||||
|
public void testNahirisSacrificePrevented() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.HAND, playerA, nahirisSacrifice);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, balduvianBears + "@bearsB");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Yasharn, Implacable Earth");
|
||||||
|
|
||||||
|
checkPlayableAbility("Can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nahirisSacrifice, false);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.mage.test.cards.single.shm;
|
||||||
|
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
public class ElsewhereFlaskTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Elsewhere Flask
|
||||||
|
{2}
|
||||||
|
Artifact
|
||||||
|
|
||||||
|
When this artifact enters, draw a card.
|
||||||
|
|
||||||
|
Sacrifice this artifact: Choose a basic land type. Each land you control becomes that type until end of turn.
|
||||||
|
*/
|
||||||
|
private static final String elsewhereFlask = "Elsewhere Flask";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testElsewhereFlask() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, elsewhereFlask);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
|
||||||
|
setChoice(playerA, "Swamp");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertType("Island", CardType.LAND, SubType.SWAMP);
|
||||||
|
assertType("Forest", CardType.LAND, SubType.SWAMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testElsewhereFlask2() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, elsewhereFlask);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
|
||||||
|
setChoice(playerA, "Swamp");
|
||||||
|
|
||||||
|
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertType("Island", CardType.LAND, SubType.ISLAND);
|
||||||
|
assertType("Forest", CardType.LAND, SubType.FOREST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.mage.test.cards.single.tdm;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class StalwartSuccessorTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Stalwart Successor
|
||||||
|
{1}{B}{G}
|
||||||
|
Creature — Human Warrior
|
||||||
|
|
||||||
|
Menace (This creature can’t be blocked except by two or more creatures.)
|
||||||
|
|
||||||
|
Whenever one or more counters are put on a creature you control, if it’s the first time counters have been put on that creature this turn, put a +1/+1 counter on that creature.
|
||||||
|
|
||||||
|
3/2
|
||||||
|
*/
|
||||||
|
private static final String stalwartSuccessor = "Stalwart Successor";
|
||||||
|
/*
|
||||||
|
Purestrain Genestealer
|
||||||
|
{2}{G}
|
||||||
|
Creature — Tyranid
|
||||||
|
|
||||||
|
This creature enters with two +1/+1 counters on it.
|
||||||
|
|
||||||
|
Vanguard Species — Whenever this creature attacks, you may remove a +1/+1 counter from it. If you do, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.
|
||||||
|
|
||||||
|
1/1
|
||||||
|
*/
|
||||||
|
private static final String purestrainGenestealer = "Purestrain Genestealer";
|
||||||
|
@Test
|
||||||
|
public void testStalwartSuccessor() {
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, stalwartSuccessor);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
|
||||||
|
addCard(Zone.HAND, playerA, purestrainGenestealer);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, purestrainGenestealer);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertCounterCount(playerA, purestrainGenestealer, CounterType.P1P1, 2 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.mage.test.cards.single.tmp;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class AlurenTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Aluren
|
||||||
|
{2}{G}{G}
|
||||||
|
Enchantment
|
||||||
|
Any player may cast creature spells with mana value 3 or less without paying their mana costs and as though they had flash.
|
||||||
|
*/
|
||||||
|
private static final String aluren = "Aluren";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bear Cub
|
||||||
|
{1}{G}
|
||||||
|
Creature — Bear
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String cub = "Bear Cub";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAluren() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, aluren);
|
||||||
|
addCard(Zone.HAND, playerA, cub);
|
||||||
|
addCard(Zone.HAND, playerB, cub);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.UPKEEP, playerA, cub);
|
||||||
|
setChoice(playerA, "Cast without paying its mana cost");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.END_TURN, playerB, cub);
|
||||||
|
setChoice(playerB, "Cast without paying its mana cost");
|
||||||
|
|
||||||
|
setStopAt(2, PhaseStep.UPKEEP);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, cub, 1);
|
||||||
|
assertPermanentCount(playerB, cub, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package org.mage.test.cards.single.tmp;
|
||||||
|
|
||||||
|
import mage.abilities.keyword.LandwalkAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class ExcavatorTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Excavator
|
||||||
|
{2}
|
||||||
|
Artifact
|
||||||
|
|
||||||
|
{T}, Sacrifice a basic land: Target creature gains landwalk of each of the land types of the sacrificed land until end of turn.
|
||||||
|
(It can’t be blocked as long as defending player controls a land of any of those types.)
|
||||||
|
*/
|
||||||
|
public static final String excavator = "Excavator";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Leyline of the Guildpact
|
||||||
|
{G/W}{G/U}{B/G}{R/G}
|
||||||
|
Enchantment
|
||||||
|
|
||||||
|
If this card is in your opening hand, you may begin the game with it on the battlefield.
|
||||||
|
|
||||||
|
Each nonland permanent you control is all colors.
|
||||||
|
|
||||||
|
Lands you control are every basic land type in addition to their other types.
|
||||||
|
*/
|
||||||
|
public static final String leylineOfTheGuildpact = "Leyline of the Guildpact";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("Failing because permanent LKI does not save MageObjectAttribute values")
|
||||||
|
public void testExcavator() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, excavator);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, leylineOfTheGuildpact);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
setChoice(playerA, "Island");
|
||||||
|
addTarget(playerA, "Balduvian Bears");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAbilityCount(playerA, "Balduvian Bears", LandwalkAbility.class, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
package org.mage.test.cards.single.who;
|
||||||
|
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.LoseGameSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.LoseLifeAllPlayersEffect;
|
||||||
|
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||||
|
|
||||||
|
public class EverybodyLivesTest extends CardTestCommander4Players {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Everybody Lives!
|
||||||
|
{1}{W}
|
||||||
|
Instant
|
||||||
|
|
||||||
|
All creatures gain hexproof and indestructible until end of turn. Players gain hexproof until end of turn.
|
||||||
|
Players can’t lose life this turn and players can’t lose the game or win the game this turn.
|
||||||
|
*/
|
||||||
|
private static final String everybodyLives = "Everybody Lives!";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEverybodyLivesCantLoseLifeAndHexproof() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCustomCardWithAbility("lose life effect", playerA, new SimpleActivatedAbility(
|
||||||
|
new LoseLifeAllPlayersEffect(20),
|
||||||
|
new ManaCostsImpl<>(""))
|
||||||
|
);
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
addCard(Zone.HAND, playerA, everybodyLives);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, everybodyLives, true);
|
||||||
|
checkPlayableAbility("Can't cast lightning bolt", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", false);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "each player");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
assertLife(playerC, 20);
|
||||||
|
assertLife(playerD, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEverybodyLivesCantLoseGame() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCustomCardWithAbility("lose game effect", playerA, new SimpleActivatedAbility(
|
||||||
|
new LoseGameSourceControllerEffect(),
|
||||||
|
new ManaCostsImpl<>(""))
|
||||||
|
);
|
||||||
|
addCard(Zone.HAND, playerA, everybodyLives);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, everybodyLives, true);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "you lose");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertHasNotLostTheGame(playerA);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEverybodyLivesCantWinGame() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCustomCardWithAbility("win game effect", playerA, new SimpleActivatedAbility(
|
||||||
|
new WinGameSourceControllerEffect(),
|
||||||
|
new ManaCostsImpl<>(""))
|
||||||
|
);
|
||||||
|
addCard(Zone.HAND, playerA, everybodyLives);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, everybodyLives, true);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "you win");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertHasNotWonTheGame(playerA);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2079,6 +2079,7 @@ public class VerifyCardDataTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSubtypes(Card card, MtgJsonCard ref) {
|
private void checkSubtypes(Card card, MtgJsonCard ref) {
|
||||||
if (skipListHaveName(SKIP_LIST_SUBTYPE, card.getExpansionSetCode(), card.getName())) {
|
if (skipListHaveName(SKIP_LIST_SUBTYPE, card.getExpansionSetCode(), card.getName())) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2343,7 +2344,11 @@ public class VerifyCardDataTest {
|
||||||
|
|
||||||
|
|
||||||
// search and check dies related abilities
|
// search and check dies related abilities
|
||||||
String rules = triggeredAbility.getRule();
|
// remove reminder text
|
||||||
|
String rules = triggeredAbility
|
||||||
|
.getRule()
|
||||||
|
.replaceAll("(?i) <i>\\(.+\\)</i>", "")
|
||||||
|
.replaceAll("(?i) \\(.+\\)", "");
|
||||||
if (ignoredAbilities.stream().anyMatch(rules::contains)) {
|
if (ignoredAbilities.stream().anyMatch(rules::contains)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,11 @@ import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
|
|
@ -47,12 +49,12 @@ public class DamageWithExcessEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int damage = amount.calculate(game, source, this);
|
int damage = amount.calculate(game, source, this);
|
||||||
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
|
int excess = permanent.damageWithExcess(damage, source, game);
|
||||||
lethal = Math.min(lethal, damage);
|
if (excess > 0) {
|
||||||
permanent.damage(lethal, source.getSourceId(), source, game);
|
Optional.ofNullable(permanent)
|
||||||
Player player = game.getPlayer(permanent.getControllerId());
|
.map(Controllable::getControllerId)
|
||||||
if (player != null && lethal < damage) {
|
.map(game::getPlayer)
|
||||||
player.damage(damage - lethal, source.getSourceId(), source, game);
|
.ifPresent(player -> player.damage(excess, source, game));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import mage.constants.Zone;
|
||||||
import mage.game.Controllable;
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.GameState;
|
import mage.game.GameState;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -177,6 +178,23 @@ public interface Permanent extends Card, Controllable {
|
||||||
|
|
||||||
int getLethalDamage(UUID attackerId, Game game);
|
int getLethalDamage(UUID attackerId, Game game);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same arguments as regular damage method, but returns the amount of excess damage dealt instead
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default int damageWithExcess(int damage, Ability source, Game game) {
|
||||||
|
return this.damageWithExcess(damage, source.getSourceId(), source, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int damageWithExcess(int damage, UUID attackerId, Ability source, Game game) {
|
||||||
|
int lethal = getLethalDamage(attackerId, game);
|
||||||
|
int excess = Math.max(CardUtil.overflowDec(damage, lethal), 0);
|
||||||
|
int dealt = Math.min(lethal, damage);
|
||||||
|
this.damage(dealt, attackerId, source, game);
|
||||||
|
return excess;
|
||||||
|
}
|
||||||
|
|
||||||
void removeAllDamage(Game game);
|
void removeAllDamage(Game game);
|
||||||
|
|
||||||
void reset(Game game);
|
void reset(Game game);
|
||||||
|
|
|
||||||
|
|
@ -38,14 +38,6 @@ public class TargetCardAndOrCardInLibrary extends TargetCardInLibrary {
|
||||||
|
|
||||||
private final PredicateCardAssignment assignment;
|
private final PredicateCardAssignment assignment;
|
||||||
|
|
||||||
/**
|
|
||||||
* a [firstType] card and/or a [secondType] card
|
|
||||||
*/
|
|
||||||
protected TargetCardAndOrCardInLibrary(Predicate<? super Card> firstPredicate, Predicate<? super Card> secondPredicate, String filterText) {
|
|
||||||
super(0, 2, makeFilter(firstPredicate, secondPredicate, filterText));
|
|
||||||
this.assignment = new PredicateCardAssignment(firstPredicate, secondPredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TargetCardAndOrCardInLibrary(CardType firstType, CardType secondType) {
|
public TargetCardAndOrCardInLibrary(CardType firstType, CardType secondType) {
|
||||||
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(
|
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(
|
||||||
CardUtil.getTextWithFirstCharLowerCase(firstType.toString()),
|
CardUtil.getTextWithFirstCharLowerCase(firstType.toString()),
|
||||||
|
|
@ -60,6 +52,14 @@ public class TargetCardAndOrCardInLibrary extends TargetCardInLibrary {
|
||||||
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(firstType.getDescription(), secondType.getDescription()));
|
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(firstType.getDescription(), secondType.getDescription()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a [firstType] card and/or a [secondType] card
|
||||||
|
*/
|
||||||
|
public TargetCardAndOrCardInLibrary(Predicate<? super Card> firstPredicate, Predicate<? super Card> secondPredicate, String filterText) {
|
||||||
|
super(0, 2, makeFilter(firstPredicate, secondPredicate, filterText));
|
||||||
|
this.assignment = new PredicateCardAssignment(firstPredicate, secondPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
protected TargetCardAndOrCardInLibrary(final TargetCardAndOrCardInLibrary target) {
|
protected TargetCardAndOrCardInLibrary(final TargetCardAndOrCardInLibrary target) {
|
||||||
super(target);
|
super(target);
|
||||||
this.assignment = target.assignment;
|
this.assignment = target.assignment;
|
||||||
|
|
|
||||||
|
|
@ -59737,7 +59737,7 @@ Flexible Waterbender|Avatar: The Last Airbender|50|C|{3}{U}|Creature - Human War
|
||||||
Geyser Leaper|Avatar: The Last Airbender|52|C|{4}{U}|Creature - Human Warrior Ally|4|3|Flying$Waterbend {4}: Draw a card, then discard a card.|
|
Geyser Leaper|Avatar: The Last Airbender|52|C|{4}{U}|Creature - Human Warrior Ally|4|3|Flying$Waterbend {4}: Draw a card, then discard a card.|
|
||||||
Giant Koi|Avatar: The Last Airbender|53|C|{4}{U}{U}|Creature - Fish|5|7|Waterbend {3}: This creature can't be blocked this turn.$Islandcycling {2}|
|
Giant Koi|Avatar: The Last Airbender|53|C|{4}{U}{U}|Creature - Fish|5|7|Waterbend {3}: This creature can't be blocked this turn.$Islandcycling {2}|
|
||||||
Iguana Parrot|Avatar: The Last Airbender|56|C|{2}{U}|Creature - Lizard Bird Pirate|2|2|Flying, vigilance$Prowess|
|
Iguana Parrot|Avatar: The Last Airbender|56|C|{2}{U}|Creature - Lizard Bird Pirate|2|2|Flying, vigilance$Prowess|
|
||||||
It'll Quench Ya!|Avatar: The Last Airbender|58|C|{1}{U}|Instant - Lesson|||Counter target spell unless its controller pays 2.|
|
It'll Quench Ya!|Avatar: The Last Airbender|58|C|{1}{U}|Instant - Lesson|||Counter target spell unless its controller pays {2}.|
|
||||||
Katara, Bending Prodigy|Avatar: The Last Airbender|59|U|{2}{U}|Legendary Creature - Human Warrior Ally|2|3|At the beginning of your end step, if Katara is tapped, put a +1/+1 counter on her.$Waterbend {6}: Draw a card.|
|
Katara, Bending Prodigy|Avatar: The Last Airbender|59|U|{2}{U}|Legendary Creature - Human Warrior Ally|2|3|At the beginning of your end step, if Katara is tapped, put a +1/+1 counter on her.$Waterbend {6}: Draw a card.|
|
||||||
Master Pakku|Avatar: The Last Airbender|63|U|{1}{U}|Legendary Creature - Human Advisor Ally|1|3|Prowess$Whenever Master Pakku becomes tapped, target player mills X cards, where X is the number of Lesson cards in your graveyard.|
|
Master Pakku|Avatar: The Last Airbender|63|U|{1}{U}|Legendary Creature - Human Advisor Ally|1|3|Prowess$Whenever Master Pakku becomes tapped, target player mills X cards, where X is the number of Lesson cards in your graveyard.|
|
||||||
Otter-Penguin|Avatar: The Last Airbender|67|C|{1}{U}|Creature - Otter Bird|2|1|Whenever you draw your second card each turn, this creature gets +1/+2 until end of turn and can't be blocked this turn.|
|
Otter-Penguin|Avatar: The Last Airbender|67|C|{1}{U}|Creature - Otter Bird|2|1|Whenever you draw your second card each turn, this creature gets +1/+2 until end of turn and can't be blocked this turn.|
|
||||||
|
|
@ -59804,6 +59804,11 @@ Toph, the First Metalbender|Avatar: The Last Airbender|247|R|{1}{R}{G}{W}|Legend
|
||||||
Vindictive Warden|Avatar: The Last Airbender|249|C|{2}{B/R}|Creature - Human Soldier|2|3|Menace$Firebending 1${3}: This creature deals 1 damage to each opponent.|
|
Vindictive Warden|Avatar: The Last Airbender|249|C|{2}{B/R}|Creature - Human Soldier|2|3|Menace$Firebending 1${3}: This creature deals 1 damage to each opponent.|
|
||||||
Barrels of Blasting Jelly|Avatar: The Last Airbender|254|C|{1}|Artifact|||{1}: Add one mana of any color. Activate only once each turn.${5}, {T}, Sacrifice this artifact: It deals 5 damage to target creature.|
|
Barrels of Blasting Jelly|Avatar: The Last Airbender|254|C|{1}|Artifact|||{1}: Add one mana of any color. Activate only once each turn.${5}, {T}, Sacrifice this artifact: It deals 5 damage to target creature.|
|
||||||
Bender's Waterskin|Avatar: The Last Airbender|255|C|{3}|Artifact|||Untap this artifact during each other player's untap step.${T}: Add one mana of any color.|
|
Bender's Waterskin|Avatar: The Last Airbender|255|C|{3}|Artifact|||Untap this artifact during each other player's untap step.${T}: Add one mana of any color.|
|
||||||
|
Plains|Avatar: The Last Airbender|282|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Island|Avatar: The Last Airbender|283|C||Basic Land - Island|||({T}: Add {U}.)|
|
||||||
|
Swamp|Avatar: The Last Airbender|284|C||Basic Land - Swamp|||({T}: Add {B}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender|285|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Forest|Avatar: The Last Airbender|286|C||Basic Land - Forest|||({T}: Add {G}.)|
|
||||||
Plains|Avatar: The Last Airbender|287|C||Basic Land - Plains|||({T}: Add {W}.)|
|
Plains|Avatar: The Last Airbender|287|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
Island|Avatar: The Last Airbender|288|C||Basic Land - Island|||({T}: Add {U}.)|
|
Island|Avatar: The Last Airbender|288|C||Basic Land - Island|||({T}: Add {U}.)|
|
||||||
Swamp|Avatar: The Last Airbender|289|C||Basic Land - Swamp|||({T}: Add {B}.)|
|
Swamp|Avatar: The Last Airbender|289|C||Basic Land - Swamp|||({T}: Add {B}.)|
|
||||||
|
|
@ -59825,6 +59830,7 @@ Katara, the Fearless|Avatar: The Last Airbender|361|R|{G}{W}{U}|Legendary Creatu
|
||||||
Toph, the First Metalbender|Avatar: The Last Airbender|362|R|{1}{R}{G}{W}|Legendary Creature - Human Warrior Ally|3|3|Nontoken artifacts you control are lands in addition to their other types.$At the beginning of your end step, earthbend 2.|
|
Toph, the First Metalbender|Avatar: The Last Airbender|362|R|{1}{R}{G}{W}|Legendary Creature - Human Warrior Ally|3|3|Nontoken artifacts you control are lands in addition to their other types.$At the beginning of your end step, earthbend 2.|
|
||||||
Avatar Aang|Avatar: The Last Airbender|363|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.|
|
Avatar Aang|Avatar: The Last Airbender|363|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.|
|
||||||
Aang, Master of Elements|Avatar: The Last Airbender|363|M||Legendary Creature - Avatar Ally|6|6|Flying$Spells you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.|
|
Aang, Master of Elements|Avatar: The Last Airbender|363|M||Legendary Creature - Avatar Ally|6|6|Flying$Spells you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.|
|
||||||
|
Hakoda, Selfless Commander|Avatar: The Last Airbender|366|R|{3}{W}|Legendary Creature - Human Warrior Ally|3|5|Vigilance$You may look at the top card of your library any time.$You may cast Ally spells from the top of your library.$Sacrifice Hakoda: Creatures you control get +0/+5 and gain indestructible until end of turn.|
|
||||||
Sokka, Bold Boomeranger|Avatar: The Last Airbender|383|R|{U}{R}|Legendary Creature - Human Warrior Ally|1|1|When Sokka enters, discard up to two cards, then draw that many cards.$Whenever you cast an artifact or Lesson spell, put a +1/+1 counter on Sokka.|
|
Sokka, Bold Boomeranger|Avatar: The Last Airbender|383|R|{U}{R}|Legendary Creature - Human Warrior Ally|1|1|When Sokka enters, discard up to two cards, then draw that many cards.$Whenever you cast an artifact or Lesson spell, put a +1/+1 counter on Sokka.|
|
||||||
Anti-Venom, Horrifying Healer|Marvel's Spider-Man|1|M|{W}{W}{W}{W}{W}|Legendary Creature - Symbiote Hero|5|5|When Anti-Venom enters, if he was cast, return target creature card from your graveyard to the battlefield.$If damage would be dealt to Anti-Venom, prevent that damage and put that many +1/+1 counters on him.|
|
Anti-Venom, Horrifying Healer|Marvel's Spider-Man|1|M|{W}{W}{W}{W}{W}|Legendary Creature - Symbiote Hero|5|5|When Anti-Venom enters, if he was cast, return target creature card from your graveyard to the battlefield.$If damage would be dealt to Anti-Venom, prevent that damage and put that many +1/+1 counters on him.|
|
||||||
Aunt May|Marvel's Spider-Man|3|U|{W}|Legendary Creature - Human Citizen|0|2|Whenever another creature you control enters, you gain 1 life. If it's a Spider, put a +1/+1 counter on it.|
|
Aunt May|Marvel's Spider-Man|3|U|{W}|Legendary Creature - Human Citizen|0|2|Whenever another creature you control enters, you gain 1 life. If it's a Spider, put a +1/+1 counter on it.|
|
||||||
|
|
@ -59940,7 +59946,7 @@ Aang, Air Nomad|Avatar: The Last Airbender Eternal|210|R|{3}{W}{W}|Legendary Cre
|
||||||
Aang's Defense|Avatar: The Last Airbender Eternal|211|C|{W}|Instant|||Target blocking creature you control gets +2/+2 until end of turn.$Draw a card.|
|
Aang's Defense|Avatar: The Last Airbender Eternal|211|C|{W}|Instant|||Target blocking creature you control gets +2/+2 until end of turn.$Draw a card.|
|
||||||
Aardvark Sloth|Avatar: The Last Airbender Eternal|212|C|{3}{W}|Creature - Sloth Beast|3|3|Lifelink|
|
Aardvark Sloth|Avatar: The Last Airbender Eternal|212|C|{3}{W}|Creature - Sloth Beast|3|3|Lifelink|
|
||||||
Allied Teamwork|Avatar: The Last Airbender Eternal|213|R|{2}{W}|Enchantment|||When this enchantment enters, create a 1/1 white Ally creature token.$Allies you control get +1/+1.|
|
Allied Teamwork|Avatar: The Last Airbender Eternal|213|R|{2}{W}|Enchantment|||When this enchantment enters, create a 1/1 white Ally creature token.$Allies you control get +1/+1.|
|
||||||
Appa, Aang's Companion|Avatar: The Last Airbender Eternal|214|U|{3}{W}|Legendary Creature - Bison Ally|2|4|Flying$Whenever Appa attacks, another target attacking creature without flying gains flying until until end of turn.|
|
Appa, Aang's Companion|Avatar: The Last Airbender Eternal|214|U|{3}{W}|Legendary Creature - Bison Ally|2|4|Flying$Whenever Appa attacks, another target attacking creature without flying gains flying until end of turn.|
|
||||||
Katara, Heroic Healer|Avatar: The Last Airbender Eternal|215|U|{4}{W}|Legendary Creature - Human Warrior Ally|2|3|Lifelink$When Katara enters, put a +1/+1 counter on each other creature you control.|
|
Katara, Heroic Healer|Avatar: The Last Airbender Eternal|215|U|{4}{W}|Legendary Creature - Human Warrior Ally|2|3|Lifelink$When Katara enters, put a +1/+1 counter on each other creature you control.|
|
||||||
Kyoshi Warrior Guard|Avatar: The Last Airbender Eternal|216|C|{1}{W}|Creature - Human Warrior Ally|2|3||
|
Kyoshi Warrior Guard|Avatar: The Last Airbender Eternal|216|C|{1}{W}|Creature - Human Warrior Ally|2|3||
|
||||||
Momo, Rambunctious Rascal|Avatar: The Last Airbender Eternal|217|U|{2}{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$When Momo enters, he deals 4 damage to target tapped creature an opponent controls.|
|
Momo, Rambunctious Rascal|Avatar: The Last Airbender Eternal|217|U|{2}{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$When Momo enters, he deals 4 damage to target tapped creature an opponent controls.|
|
||||||
|
|
@ -59991,3 +59997,43 @@ Thriving Grove|Avatar: The Last Airbender Eternal|261|C||Land|||This land enters
|
||||||
Thriving Heath|Avatar: The Last Airbender Eternal|262|C||Land|||This land enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.|
|
Thriving Heath|Avatar: The Last Airbender Eternal|262|C||Land|||This land enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.|
|
||||||
Thriving Isle|Avatar: The Last Airbender Eternal|263|C||Land|||This land enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.|
|
Thriving Isle|Avatar: The Last Airbender Eternal|263|C||Land|||This land enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.|
|
||||||
Thriving Moor|Avatar: The Last Airbender Eternal|264|C||Land|||This land enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.|
|
Thriving Moor|Avatar: The Last Airbender Eternal|264|C||Land|||This land enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.|
|
||||||
|
Aang, Air Nomad|Avatar: The Last Airbender Eternal|265|R|{3}{W}{W}|Legendary Creature - Human Avatar Ally|5|4|Flying$Vigilance$Other creatures you control have vigilance.|
|
||||||
|
Aang's Defense|Avatar: The Last Airbender Eternal|266|C|{W}|Instant|||Target blocking creature you control gets +2/+2 until end of turn.$Draw a card.|
|
||||||
|
Aardvark Sloth|Avatar: The Last Airbender Eternal|267|C|{3}{W}|Creature - Sloth Beast|3|3|Lifelink|
|
||||||
|
Appa, Aang's Companion|Avatar: The Last Airbender Eternal|268|U|{3}{W}|Legendary Creature - Bison Ally|2|4|Flying$Whenever Appa attacks, another target attacking creature without flying gains flying until end of turn.|
|
||||||
|
Katara, Heroic Healer|Avatar: The Last Airbender Eternal|269|U|{4}{W}|Legendary Creature - Human Warrior Ally|2|3|Lifelink$When Katara enters, put a +1/+1 counter on each other creature you control.|
|
||||||
|
Momo, Rambunctious Rascal|Avatar: The Last Airbender Eternal|270|U|{2}{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$When Momo enters, he deals 4 damage to target tapped creature an opponent controls.|
|
||||||
|
Path to Redemption|Avatar: The Last Airbender Eternal|271|C|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.${5}, Sacrifice this Aura: Exile enchanted creature. Create a 1/1 white Ally creature token. Activate only during your turn.|
|
||||||
|
Razor Rings|Avatar: The Last Airbender Eternal|272|C|{1}{W}|Instant|||Razor Rings deals 4 damage to target attacking or blocking creature. You gain life equal to the excess damage dealt this way.|
|
||||||
|
Sledding Otter-Penguin|Avatar: The Last Airbender Eternal|273|C|{2}{W}|Creature - Otter Bird|2|3|{3}: Put a +1/+1 counter on this creature.|
|
||||||
|
Sokka, Wolf Cove's Protector|Avatar: The Last Airbender Eternal|274|U|{2}{W}|Legendary Creature - Human Warrior Ally|3|3|Vigilance|
|
||||||
|
Tundra Wall|Avatar: The Last Airbender Eternal|275|C|{1}{W}|Creature - Wall|0|4|Defender|
|
||||||
|
Wolf Cove Villager|Avatar: The Last Airbender Eternal|276|C|{W}|Creature - Human Peasant|2|2|This creature enters tapped.|
|
||||||
|
Capital Guard|Avatar: The Last Airbender Eternal|277|C|{1}{R}|Creature - Human Soldier|2|2||
|
||||||
|
Dragon Moose|Avatar: The Last Airbender Eternal|278|C|{3}{R}|Creature - Dragon Elk|3|3|Haste|
|
||||||
|
Explosive Shot|Avatar: The Last Airbender Eternal|279|C|{1}{R}|Sorcery|||Explosive Shot deals 4 damage to target creature.|
|
||||||
|
Fire Nation Soldier|Avatar: The Last Airbender Eternal|280|C|{2}{R}|Creature - Human Soldier|3|2|Haste|
|
||||||
|
Fire Nation's Conquest|Avatar: The Last Airbender Eternal|281|U|{2}{R}|Enchantment|||Creatures you control get +1/+0.|
|
||||||
|
Iroh, Firebending Instructor|Avatar: The Last Airbender Eternal|282|U|{2}{R}|Legendary Creature - Human Noble Ally|2|2|Whenever Iroh attacks, attacking creatures get +1/+1 until end of turn.|
|
||||||
|
Komodo Rhino|Avatar: The Last Airbender Eternal|283|C|{3}{R}|Creature - Lizard Rhino|5|2|Trample|
|
||||||
|
Run Amok|Avatar: The Last Airbender Eternal|284|C|{1}{R}|Instant|||Target attacking creature gets +3/+3 and gains trample until end of turn.|
|
||||||
|
Warship Scout|Avatar: The Last Airbender Eternal|285|C|{R}|Creature - Human Scout|2|1||
|
||||||
|
Zhao, the Seething Flame|Avatar: The Last Airbender Eternal|286|U|{4}{R}|Legendary Creature - Human Soldier|5|5|Menace|
|
||||||
|
Zuko, Avatar Hunter|Avatar: The Last Airbender Eternal|287|R|{3}{R}{R}|Legendary Creature - Human Noble|4|5|Reach$Whenever you cast a red spell, create a 2/2 red Soldier creature token.|
|
||||||
|
Zuko's Offense|Avatar: The Last Airbender Eternal|288|C|{R}|Sorcery|||Zuko's Offense deals 2 damage to any target.|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|289|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|290|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|291|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|292|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|293|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|294|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|295|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Mountain|Avatar: The Last Airbender Eternal|296|C||Basic Land - Mountain|||({T}: Add {R}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|297|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|298|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|299|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|300|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|301|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|302|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|303|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
Plains|Avatar: The Last Airbender Eternal|304|C||Basic Land - Plains|||({T}: Add {W}.)|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue