mirror of
https://github.com/correl/mage.git
synced 2024-11-14 19:19:32 +00:00
[ONE] Implement The Eternal Wanderer (#10000)
This commit is contained in:
parent
3305f3c8cd
commit
4ac4ba2003
4 changed files with 301 additions and 0 deletions
223
Mage.Sets/src/mage/cards/t/TheEternalWanderer.java
Normal file
223
Mage.Sets/src/mage/cards/t/TheEternalWanderer.java
Normal file
|
@ -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<Permanent> 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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue