diff --git a/Mage.Sets/src/mage/cards/t/TheEternalWanderer.java b/Mage.Sets/src/mage/cards/t/TheEternalWanderer.java new file mode 100644 index 00000000000..a760fb1b17a --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheEternalWanderer.java @@ -0,0 +1,223 @@ +package mage.cards.t; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.target.TargetPermanent; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.DoublestrikeSamuraiToken; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + + +/** + * + * @author @stwalsh4118 + */ +public final class TheEternalWanderer extends CardImpl { + + private static final FilterPermanent filter + = new FilterPermanent(); + + static { + filter.add(Predicates.or( + CardType.ARTIFACT.getPredicate(), + CardType.CREATURE.getPredicate() + )); + } + + public TheEternalWanderer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{W}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.setStartingLoyalty(5); + + // No more than one creature can attack The Eternal Wanderer each combat. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TheEternalWandererAttackRestrictionEffect())); + + // +1: Exile up to one target artifact or creature. Return that card to the battlefield under its owner's control at the beginning of that player's next end step. + Ability ability = new LoyaltyAbility(new TheEternalWandererExileEffect(), 1); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + + // 0: Create a 2/2 white Samurai creature token with double strike. + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DoublestrikeSamuraiToken()), 0)); + + // -4: For each player, choose a creature that player controls. Each player sacrifices all creatures they control not chosen this way. + this.addAbility(new LoyaltyAbility(new TheEternalWandererSacrificeEffect(), -4)); + } + + private TheEternalWanderer(final TheEternalWanderer card) { + super(card); + } + + @Override + public TheEternalWanderer copy() { + return new TheEternalWanderer(this); + } +} + +class TheEternalWandererExileEffect extends OneShotEffect { + + public TheEternalWandererExileEffect() { + super(Outcome.Detriment); + staticText = "Exile up to one target artifact or creature. Return that card to the battlefield " + + "under its owner's control at the beginning of that player's next end step."; + } + + public TheEternalWandererExileEffect(final TheEternalWandererExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + System.out.println(permanent); + if (permanent != null) { + UUID exileId = UUID.randomUUID(); + if (controller.moveCardsToExile(permanent, source, game, true, exileId, sourceObject.getIdName())) { + //create delayed triggered ability + Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); + effect.setTargetPointer(new FixedTarget(permanent.getId(), game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility(effect, permanent.getOwnerId()), source); + } + } + return true; + } + return false; + } + + @Override + public TheEternalWandererExileEffect copy() { + return new TheEternalWandererExileEffect(this); + } +} + +class TheEternalWandererSacrificeEffect extends OneShotEffect { + + public TheEternalWandererSacrificeEffect() { + super(Outcome.Detriment); + staticText = "For each player, choose a creature that player controls. Each player sacrifices all creatures they control not chosen this way"; + } + + public TheEternalWandererSacrificeEffect(final TheEternalWandererSacrificeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Set chosenPermanents = new HashSet<>(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent("a creature of " + player.getName()); + filterCreaturePermanent.add(new ControllerIdPredicate(playerId)); + TargetPermanent target = new TargetPermanent(1, 1, filterCreaturePermanent, true); + + + if (target.canChoose(controller.getId(), source, game)) { + controller.chooseTarget(Outcome.Benefit, target, source, game); + Permanent creature = game.getPermanent(target.getFirstTarget()); + if (creature != null) { + chosenPermanents.add(creature); + } + target.clearChosen(); + } + } + } + // Then each player sacrifices all other nonland permanents they control + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURES, playerId, game)) { + if (!chosenPermanents.contains(permanent)) { + permanent.sacrifice(source, game); + } + } + } + } + + return true; + } + + return false; + } + + @Override + public TheEternalWandererSacrificeEffect copy() { + return new TheEternalWandererSacrificeEffect(this); + } +} + +class TheEternalWandererAttackRestrictionEffect extends RestrictionEffect { + + TheEternalWandererAttackRestrictionEffect() { + super(Duration.WhileOnBattlefield); + staticText = "No more than one creature can attack" + + " The Eternal Wanderer each combat"; + } + + TheEternalWandererAttackRestrictionEffect(final TheEternalWandererAttackRestrictionEffect effect) { + super(effect); + } + + @Override + public TheEternalWandererAttackRestrictionEffect copy() { + return new TheEternalWandererAttackRestrictionEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return true; + } + + @Override + public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) { + + if(defenderId == null || attacker == null || source == null){ + return true; + } + + //Check if attacking The Eternal Wanderer + if(defenderId.equals(source.getSourceId())){ + + //If there is already a creature attacking The Eternal Wanderer, dont let another creature attack it + for(CombatGroup group : game.getCombat().getGroups()){ + if(group.getDefenderId().equals(source.getSourceId())){ + return false; + } + } + return true; + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOne.java b/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOne.java index 8015cf94b2f..d33bac16a3e 100644 --- a/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOne.java +++ b/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOne.java @@ -217,6 +217,7 @@ public final class PhyrexiaAllWillBeOne extends ExpansionSet { cards.add(new SetCardInfo("Testament Bearer", 111, Rarity.COMMON, mage.cards.t.TestamentBearer.class)); cards.add(new SetCardInfo("The Autonomous Furnace", 247, Rarity.COMMON, mage.cards.t.TheAutonomousFurnace.class)); cards.add(new SetCardInfo("The Dross Pits", 251, Rarity.COMMON, mage.cards.t.TheDrossPits.class)); + cards.add(new SetCardInfo("The Eternal Wanderer", 11, Rarity.RARE, mage.cards.t.TheEternalWanderer.class)); cards.add(new SetCardInfo("The Fair Basilica", 252, Rarity.COMMON, mage.cards.t.TheFairBasilica.class)); cards.add(new SetCardInfo("The Filigree Sylex", 227, Rarity.RARE, mage.cards.t.TheFiligreeSylex.class)); cards.add(new SetCardInfo("The Hunter Maze", 253, Rarity.COMMON, mage.cards.t.TheHunterMaze.class)); diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility.java new file mode 100644 index 00000000000..abbae47b253 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility.java @@ -0,0 +1,46 @@ +package mage.abilities.common.delayed; + +import java.util.UUID; + +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.events.GameEvent; + +public class AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility extends DelayedTriggeredAbility { + + protected UUID playerId; + + + public AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility(Effect effect, UUID playerId) { + super(effect, Duration.Custom, true, false); + this.playerId = playerId; + } + + public AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility(final AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility ability) { + super(ability); + this.playerId = ability.playerId; + } + + @Override + public AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility copy() { + return new AtTheBeginOfPlayersNextEndStepDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.END_TURN_STEP_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.getActivePlayerId().equals(playerId); + } + + @Override + public String getRule() { + return "At the beginning of its owners next end step, " + super.getRule(); + } + +} diff --git a/Mage/src/main/java/mage/game/permanent/token/DoublestrikeSamuraiToken.java b/Mage/src/main/java/mage/game/permanent/token/DoublestrikeSamuraiToken.java new file mode 100644 index 00000000000..f2363671d56 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DoublestrikeSamuraiToken.java @@ -0,0 +1,31 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author @stwalsh4118 + */ +public class DoublestrikeSamuraiToken extends TokenImpl { + + public DoublestrikeSamuraiToken() { + super("Samurai Token", "2/2 white Samurai creature token with double strike."); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add(SubType.SAMURAI); + power = new MageInt(2); + toughness = new MageInt(2); + addAbility(DoubleStrikeAbility.getInstance()); + } + + private DoublestrikeSamuraiToken(final DoublestrikeSamuraiToken token) { + super(token); + } + + @Override + public DoublestrikeSamuraiToken copy() { + return new DoublestrikeSamuraiToken(this); + } +}