[CLB] Implement Lae'zel's Acrobatics. Changed similar cards to use common logic (#9856)

This commit is contained in:
Rowan Gudmundsson 2023-03-01 10:50:14 -08:00 committed by GitHub
parent 049dd48d0a
commit d5e74dd710
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 188 additions and 43 deletions

View file

@ -12,12 +12,11 @@ import mage.constants.Outcome;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import mage.util.ExileUtil;
import java.util.HashSet;
import java.util.Set;
@ -29,12 +28,12 @@ import java.util.UUID;
public final class EerieInterlude extends CardImpl {
public EerieInterlude(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
super(ownerId, setInfo, new CardType[] {CardType.INSTANT}, "{2}{W}");
// Exile any number of target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step.
// Exile any number of target creatures you control. Return those cards to the
// battlefield under their owner's control at the beginning of the next end step.
this.getSpellAbility().addEffect(new EerieInterludeEffect());
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, new FilterControlledCreaturePermanent(), false));
}
private EerieInterlude(final EerieInterlude card) {
@ -73,22 +72,8 @@ class EerieInterludeEffect extends OneShotEffect {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);

View file

@ -0,0 +1,139 @@
package mage.cards.l;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.effects.common.RollDieWithResultTableEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.constants.CardType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.players.Player;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import mage.util.ExileUtil;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class LaezelsAcrobatics extends CardImpl {
public LaezelsAcrobatics(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[] { CardType.INSTANT }, "{3}{W}");
this.getSpellAbility().addEffect(new LaezelsAcrobaticsEffect());
}
private LaezelsAcrobatics(final LaezelsAcrobatics card) {
super(card);
}
@Override
public LaezelsAcrobatics copy() {
return new LaezelsAcrobatics(this);
}
}
class LaezelsAcrobaticsEffect extends RollDieWithResultTableEffect {
LaezelsAcrobaticsEffect() {
super(20, "Exile all nontoken creatures you control, then roll a d20");
this.addTableEntry(
1, 9,
new InfoEffect("Return those cards to the battlefield under their owner's control at the " +
"beginning of the next end step."));
this.addTableEntry(
10, 20,
new InfoEffect(
"Return those cards to the battlefield under their owner's control, then exile them again. Return those cards to the battlefield under their owner's control at the beginning of the next end step."));
}
private LaezelsAcrobaticsEffect(final LaezelsAcrobaticsEffect effect) {
super(effect);
}
@Override
public LaezelsAcrobaticsEffect copy() {
return new LaezelsAcrobaticsEffect(this);
}
private static final FilterCreaturePermanent creatureFilter = new FilterCreaturePermanent();
static {
creatureFilter.add(TokenPredicate.FALSE);
}
private Set<Card> getNontokenCreatureCards(Game game, Player player) {
List<Permanent> playerPermanents = game
.getState()
.getBattlefield()
.getActivePermanents(creatureFilter, player.getId(), game);
Set<Card> toExile = new HashSet<>();
for (Permanent permanent : playerPermanents) {
if (permanent != null) {
toExile.add(permanent);
}
}
return toExile;
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (player == null) {
return false;
}
Set<Card> toExile = getNontokenCreatureCards(game, player);
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
player.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Integer result = player.rollDice(outcome, source, game, 20);
Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
if (result < 10) {
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
effect);
game.addDelayedTriggeredAbility(delayedAbility, source);
} else {
effect.apply(game, source);
toExile = getNontokenCreatureCards(game, player);
exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
player.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game);
effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
effect);
game.addDelayedTriggeredAbility(delayedAbility, source);
}
return true;
}
}

View file

@ -18,12 +18,11 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import mage.util.ExileUtil;
import java.util.Set;
import java.util.UUID;
@ -35,7 +34,7 @@ import java.util.stream.Collectors;
public final class YorionSkyNomad extends CardImpl {
public YorionSkyNomad(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}");
super(ownerId, setInfo, new CardType[] {CardType.CREATURE}, "{3}{W/U}{W/U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BIRD);
@ -49,7 +48,8 @@ public final class YorionSkyNomad extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Yorion enters the battlefield, exile any number of other nonland permanents you own and control. Return those cards to the battlefield at the beginning of the next end step.
// When Yorion enters the battlefield, exile any number of other nonland permanents you own
// and control. Return those cards to the battlefield at the beginning of the next end step.
this.addAbility(new EntersBattlefieldTriggeredAbility(new YorionSkyNomadEffect()));
}
@ -79,8 +79,7 @@ enum YorionSkyNomadCompanionCondition implements CompanionCondition {
class YorionSkyNomadEffect extends OneShotEffect {
private static final FilterPermanent filter
= new FilterControlledPermanent("other nonland permanents you own and control");
private static final FilterPermanent filter = new FilterControlledPermanent("other nonland permanents you own and control");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
@ -116,22 +115,8 @@ class YorionSkyNomadEffect extends OneShotEffect {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);

View file

@ -341,6 +341,8 @@ public final class CommanderLegendsBattleForBaldursGate extends ExpansionSet {
cards.add(new SetCardInfo("Kindred Discovery", 81, Rarity.RARE, mage.cards.k.KindredDiscovery.class));
cards.add(new SetCardInfo("Kodama's Reach", 826, Rarity.COMMON, mage.cards.k.KodamasReach.class));
cards.add(new SetCardInfo("Korlessa, Scale Singer", 280, Rarity.UNCOMMON, mage.cards.k.KorlessaScaleSinger.class));
cards.add(new SetCardInfo("Lae'zel's Acrobatics", 30, Rarity.RARE, mage.cards.l.LaezelsAcrobatics.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lae'zel's Acrobatics", 556, Rarity.RARE, mage.cards.l.LaezelsAcrobatics.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lae'zel, Vlaakith's Champion", 29, Rarity.RARE, mage.cards.l.LaezelVlaakithsChampion.class));
cards.add(new SetCardInfo("Laelia, the Blade Reforged", 801, Rarity.RARE, mage.cards.l.LaeliaTheBladeReforged.class));
cards.add(new SetCardInfo("Lantern of Revealing", 318, Rarity.COMMON, mage.cards.l.LanternOfRevealing.class));

View file

@ -0,0 +1,34 @@
package mage.util;
import java.util.Set;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.MeldCard;
import mage.game.Game;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
public class ExileUtil {
public static Cards returnCardsFromExile(Set<Card> cards, Game game) {
Cards cardsToReturn = new CardsImpl();
for (Card exiled : cards) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
return cardsToReturn;
}
}