diff --git a/Mage.Sets/src/mage/cards/g/GideonChampionOfJustice.java b/Mage.Sets/src/mage/cards/g/GideonChampionOfJustice.java index bdf5924d09..93e3ba6cf0 100644 --- a/Mage.Sets/src/mage/cards/g/GideonChampionOfJustice.java +++ b/Mage.Sets/src/mage/cards/g/GideonChampionOfJustice.java @@ -1,8 +1,7 @@ - package mage.cards.g; -import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; @@ -16,26 +15,27 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SuperType; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.*; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.token.TokenImpl; +import mage.players.Player; import mage.target.common.TargetOpponent; +import java.util.Objects; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class GideonChampionOfJustice extends CardImpl { public GideonChampionOfJustice(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{W}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.GIDEON); @@ -56,7 +56,6 @@ public final class GideonChampionOfJustice extends CardImpl { // -15: Exile all other permanents. this.addAbility(new LoyaltyAbility(new GideonExileAllOtherPermanentsEffect(), -15)); - } private GideonChampionOfJustice(final GideonChampionOfJustice card) { @@ -71,12 +70,12 @@ public final class GideonChampionOfJustice extends CardImpl { class GideonExileAllOtherPermanentsEffect extends OneShotEffect { - public GideonExileAllOtherPermanentsEffect() { + GideonExileAllOtherPermanentsEffect() { super(Outcome.Exile); - staticText = "Exile all other permanents"; + staticText = "exile all other permanents"; } - public GideonExileAllOtherPermanentsEffect(final GideonExileAllOtherPermanentsEffect effect) { + private GideonExileAllOtherPermanentsEffect(final GideonExileAllOtherPermanentsEffect effect) { super(effect); } @@ -87,18 +86,27 @@ class GideonExileAllOtherPermanentsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { - if (!permanent.getId().equals(source.getSourceId())) { - permanent.moveToExile(null, null, source, game); - } + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; } - return true; + MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game); + Cards cards = new CardsImpl(); + game.getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT, + source.getControllerId(), game + ).stream() + .filter(Objects::nonNull) + .filter(permanent -> !mor.refersTo(permanent, game)) + .forEach(cards::add); + return player.moveCards(cards, Zone.EXILED, source, game); } } class GideonChampionOfJusticeToken extends TokenImpl { - public GideonChampionOfJusticeToken() { + GideonChampionOfJusticeToken() { super("", "indestructible Human Soldier creature with power and toughness each equal to the number of loyalty counters on him"); cardType.add(CardType.CREATURE); subtype.add(SubType.HUMAN); @@ -109,7 +117,8 @@ class GideonChampionOfJusticeToken extends TokenImpl { this.addAbility(IndestructibleAbility.getInstance()); } - public GideonChampionOfJusticeToken(final GideonChampionOfJusticeToken token) { + + private GideonChampionOfJusticeToken(final GideonChampionOfJusticeToken token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java b/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java index 84fde58cee..70677d46ea 100644 --- a/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java +++ b/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java @@ -4,7 +4,6 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.BeginningOfCombatTriggeredAbility; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.HasteAbility; @@ -18,10 +17,13 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.EmptyToken; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; -import mage.target.targetpointer.FixedTarget; +import mage.target.targetpointer.FixedTargets; import mage.util.CardUtil; +import java.util.List; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * @author jeffwadsworth @@ -32,8 +34,9 @@ public final class GodPharaohsGift extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}"); // At the beginning of combat on your turn, you may exile a creature card from your graveyard. If you do, create a token that's a copy of that card, except it's a 4/4 black Zombie. It gains haste until end of turn. - this.addAbility(new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, new GodPharaohsGiftEffect(), TargetController.YOU, true, false)); - + this.addAbility(new BeginningOfCombatTriggeredAbility( + new GodPharaohsGiftEffect(), TargetController.YOU, false + )); } private GodPharaohsGift(final GodPharaohsGift card) { @@ -48,14 +51,14 @@ public final class GodPharaohsGift extends CardImpl { class GodPharaohsGiftEffect extends OneShotEffect { - private final UUID exileId = UUID.randomUUID(); - - public GodPharaohsGiftEffect() { + GodPharaohsGiftEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "you may exile a creature card from your graveyard. If you do, create a token that's a copy of that card, except it's a 4/4 black Zombie. It gains haste until end of turn"; + this.staticText = "you may exile a creature card from your graveyard. " + + "If you do, create a token that's a copy of that card, " + + "except it's a 4/4 black Zombie. It gains haste until end of turn"; } - public GodPharaohsGiftEffect(final GodPharaohsGiftEffect effect) { + private GodPharaohsGiftEffect(final GodPharaohsGiftEffect effect) { super(effect); } @@ -68,35 +71,38 @@ class GodPharaohsGiftEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject != null) { - TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); - target.setNotTarget(true); - if (!controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD, game).isEmpty() - && controller.choose(Outcome.PutCreatureInPlay, target, source.getId(), game)) { - Card cardChosen = game.getCard(target.getFirstTarget()); - if (cardChosen != null - && cardChosen.moveToExile(exileId, sourceObject.getIdName(), source, game)) { - // create token and modify all attributes permanently (without game usage) - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(cardChosen, game); - token.removePTCDA(); - token.getPower().modifyBaseValue(4); - token.getToughness().modifyBaseValue(4); - token.getColor().setColor(ObjectColor.BLACK); - token.removeAllCreatureTypes(); - token.addSubType(SubType.ZOMBIE); - if (token.putOntoBattlefield(1, game, source, source.getControllerId())) { - Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); - if (tokenPermanent != null) { - ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(tokenPermanent.getId())); - game.addEffect(effect, source); - } - } - } - } - return true; + if (controller == null || sourceObject == null) { + return false; } - return false; + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard( + 0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD, true + ); + controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game); + Card cardChosen = game.getCard(target.getFirstTarget()); + if (cardChosen == null || !controller.moveCards(cardChosen, Zone.EXILED, source, game)) { + return false; + } + // create token and modify all attributes permanently (without game usage) + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(cardChosen, game); + token.removePTCDA(); + token.getPower().modifyBaseValue(4); + token.getToughness().modifyBaseValue(4); + token.getColor().setColor(ObjectColor.BLACK); + token.removeAllCreatureTypes(); + token.addSubType(SubType.ZOMBIE); + token.putOntoBattlefield(1, game, source, source.getControllerId()); + List permanents = token + .getLastAddedTokenIds() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (!permanents.isEmpty()) { + game.addEffect(new GainAbilityTargetEffect( + HasteAbility.getInstance(), Duration.EndOfTurn + ).setTargetPointer(new FixedTargets(permanents, game)), source); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/g/GraveyardShovel.java b/Mage.Sets/src/mage/cards/g/GraveyardShovel.java index 70c437a683..e6e9e9dc9a 100644 --- a/Mage.Sets/src/mage/cards/g/GraveyardShovel.java +++ b/Mage.Sets/src/mage/cards/g/GraveyardShovel.java @@ -1,7 +1,5 @@ - package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -18,17 +16,18 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** - * * @author North */ public final class GraveyardShovel extends CardImpl { public GraveyardShovel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // {2}, {tap}: Target player exiles a card from their graveyard. If it's a creature card, you gain 2 life. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GraveyardShovelEffect(), new GenericManaCost(2)); + Ability ability = new SimpleActivatedAbility(new GraveyardShovelEffect(), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); @@ -46,12 +45,12 @@ public final class GraveyardShovel extends CardImpl { class GraveyardShovelEffect extends OneShotEffect { - public GraveyardShovelEffect() { + GraveyardShovelEffect() { super(Outcome.Exile); this.staticText = "Target player exiles a card from their graveyard. If it's a creature card, you gain 2 life"; } - public GraveyardShovelEffect(final GraveyardShovelEffect effect) { + private GraveyardShovelEffect(final GraveyardShovelEffect effect) { super(effect); } @@ -64,19 +63,20 @@ class GraveyardShovelEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer != null && controller != null) { - TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(); - if (targetPlayer.chooseTarget(Outcome.Exile, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.moveToExile(null, "", source, game); - if (card.isCreature()) { - controller.gainLife(2, game, source); - } - } - return true; - } + if (targetPlayer == null || controller == null || targetPlayer.getGraveyard().isEmpty()) { + return false; } - return false; + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(); + target.setNotTarget(true); + targetPlayer.chooseTarget(Outcome.Exile, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return true; + } + targetPlayer.moveCards(card, Zone.EXILED, source, game); + if (card.isCreature()) { + controller.gainLife(2, game, source); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/g/GruesomeEncore.java b/Mage.Sets/src/mage/cards/g/GruesomeEncore.java index 086d893415..121c55b108 100644 --- a/Mage.Sets/src/mage/cards/g/GruesomeEncore.java +++ b/Mage.Sets/src/mage/cards/g/GruesomeEncore.java @@ -1,7 +1,5 @@ - package mage.cards.g; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; @@ -27,8 +25,9 @@ import mage.players.Player; import mage.target.common.TargetCardInOpponentsGraveyard; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author North */ public final class GruesomeEncore extends CardImpl { @@ -40,6 +39,7 @@ public final class GruesomeEncore extends CardImpl { // Put target creature card from an opponent's graveyard onto the battlefield under your control. It gains haste. this.getSpellAbility().addEffect(new GruesomeEncoreEffect()); + // Exile it at the beginning of the next end step. If that creature would leave the battlefield, exile it instead of putting it anywhere else. this.getSpellAbility().addEffect(new GruesomeEncoreReplacementEffect()); this.getSpellAbility().addTarget(new TargetCardInOpponentsGraveyard(filter)); @@ -57,12 +57,12 @@ public final class GruesomeEncore extends CardImpl { class GruesomeEncoreEffect extends OneShotEffect { - public GruesomeEncoreEffect() { + GruesomeEncoreEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Put target creature card from an opponent's graveyard onto the battlefield under your control. It gains haste. Exile it at the beginning of the next end step"; } - public GruesomeEncoreEffect(final GruesomeEncoreEffect effect) { + private GruesomeEncoreEffect(final GruesomeEncoreEffect effect) { super(effect); } @@ -104,7 +104,7 @@ class GruesomeEncoreReplacementEffect extends ReplacementEffectImpl { staticText = "If that creature would leave the battlefield, exile it instead of putting it anywhere else"; } - GruesomeEncoreReplacementEffect(final GruesomeEncoreReplacementEffect effect) { + private GruesomeEncoreReplacementEffect(final GruesomeEncoreReplacementEffect effect) { super(effect); } @@ -115,11 +115,9 @@ class GruesomeEncoreReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player player = game.getPlayer(source.getSourceId()); Card card = game.getCard(source.getFirstTarget()); - if (card != null) { - card.moveToExile(null, "", source, game); - } - return true; + return player != null && card != null && player.moveCards(card, Zone.EXILED, source, game); } @Override diff --git a/Mage.Sets/src/mage/cards/h/HauntingEchoes.java b/Mage.Sets/src/mage/cards/h/HauntingEchoes.java index 98aea73adc..015ca6785b 100644 --- a/Mage.Sets/src/mage/cards/h/HauntingEchoes.java +++ b/Mage.Sets/src/mage/cards/h/HauntingEchoes.java @@ -2,21 +2,19 @@ package mage.cards.h; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.StaticFilters; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.Predicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; import mage.util.CardUtil; -import java.util.List; +import java.util.Objects; import java.util.UUID; /** @@ -27,8 +25,8 @@ public final class HauntingEchoes extends CardImpl { public HauntingEchoes(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}"); - this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new HauntingEchoesEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); } private HauntingEchoes(final HauntingEchoes card) { @@ -43,50 +41,59 @@ public final class HauntingEchoes extends CardImpl { class HauntingEchoesEffect extends OneShotEffect { - public HauntingEchoesEffect() { + HauntingEchoesEffect() { super(Outcome.Detriment); - staticText = "Exile all cards from target player's graveyard other than basic land cards. For each card exiled this way, search that player's library for all cards with the same name as that card and exile them. Then that player shuffles their library"; + staticText = "Exile all cards from target player's graveyard other than basic land cards. " + + "For each card exiled this way, search that player's library for all cards " + + "with the same name as that card and exile them. Then that player shuffles their library"; } - public HauntingEchoesEffect(final HauntingEchoesEffect effect) { + private HauntingEchoesEffect(final HauntingEchoesEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - if (targetPlayer != null && player != null) { - for (Card card : targetPlayer.getGraveyard().getCards(game)) { - if (!StaticFilters.FILTER_CARD_BASIC_LAND.match(card, game)) { - card.moveToExile(null, "", source, game); - - String nameToSearch = CardUtil.getCardNameForSameNameSearch(card); - FilterCard filterCard = new FilterCard("cards named " + nameToSearch); - filterCard.add(new NamePredicate(nameToSearch)); - - int count = targetPlayer.getLibrary().count(filterCard, game); - TargetCardInLibrary target = new TargetCardInLibrary(count, count, filterCard); - - player.searchLibrary(target, source, game, targetPlayer.getId()); - List targets = target.getTargets(); - for (UUID cardId : targets) { - Card libraryCard = game.getCard(cardId); - if (libraryCard != null) { - libraryCard.moveToExile(null, "", source, game); - } - } - } - } - targetPlayer.shuffleLibrary(source, game); - return true; + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(source.getFirstTarget()); + if (controller == null || player == null) { + return false; } - return false; + Cards cards = new CardsImpl(); + player.getGraveyard() + .getCards(game) + .stream() + .filter(Objects::nonNull) + .filter(card -> !card.isBasic() || !card.isLand()) + .forEach(cards::add); + controller.moveCards(cards, Zone.EXILED, source, game); + cards.removeIf(uuid -> game.getState().getZone(uuid) != Zone.EXILED); + FilterCard filter = new FilterCard("cards with the same name as a card exiled this way"); + filter.add(new HauntingEchoesPredicate(cards)); + TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, filter); + controller.searchLibrary(target, source, game, player.getId()); + cards.clear(); + cards.addAll(target.getTargets()); + controller.moveCards(cards, Zone.EXILED, source, game); + player.shuffleLibrary(source, game); + return true; } @Override public HauntingEchoesEffect copy() { return new HauntingEchoesEffect(this); } - +} + +class HauntingEchoesPredicate implements Predicate { + private final Cards cards = new CardsImpl(); + + HauntingEchoesPredicate(Cards cards) { + this.cards.addAll(cards); + } + + @Override + public boolean apply(Card input, Game game) { + return cards.getCards(game).stream().anyMatch(card -> CardUtil.haveSameNames(input, card)); + } } diff --git a/Mage.Sets/src/mage/cards/h/HolyJusticiar.java b/Mage.Sets/src/mage/cards/h/HolyJusticiar.java index fbdf88a701..f0e7330b92 100644 --- a/Mage.Sets/src/mage/cards/h/HolyJusticiar.java +++ b/Mage.Sets/src/mage/cards/h/HolyJusticiar.java @@ -1,7 +1,5 @@ - package mage.cards.h; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -16,16 +14,18 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class HolyJusticiar extends CardImpl { public HolyJusticiar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); @@ -33,11 +33,10 @@ public final class HolyJusticiar extends CardImpl { this.toughness = new MageInt(1); // {2}{W}, {tap}: Tap target creature. If that creature is a Zombie, exile it. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HolyJusticiarEffect(), new ManaCostsImpl("{2}{W}")); + Ability ability = new SimpleActivatedAbility(new HolyJusticiarEffect(), new ManaCostsImpl("{2}{W}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - } private HolyJusticiar(final HolyJusticiar card) { @@ -52,28 +51,27 @@ public final class HolyJusticiar extends CardImpl { class HolyJusticiarEffect extends OneShotEffect { - public HolyJusticiarEffect() { + HolyJusticiarEffect() { super(Outcome.Detriment); - staticText = "Tap target creature. If that creature is a Zombie, exile it"; + staticText = "Tap target creature. If that creature is a Zombie, exile it"; } - public HolyJusticiarEffect(final HolyJusticiarEffect effect) { + private HolyJusticiarEffect(final HolyJusticiarEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); Permanent creature = game.getPermanent(source.getFirstTarget()); - if (creature != null) { - if (creature.hasSubtype(SubType.ZOMBIE, game)) { - creature.tap(source, game); - creature.moveToExile(source.getSourceId(), creature.getName(), source, game); - } else { - creature.tap(source, game); - } - return true; + if (player == null || creature == null) { + return false; } - return false; + creature.tap(source, game); + if (creature.hasSubtype(SubType.ZOMBIE, game)) { + player.moveCards(creature, Zone.EXILED, source, game); + } + return true; } @Override @@ -81,4 +79,3 @@ class HolyJusticiarEffect extends OneShotEffect { return new HolyJusticiarEffect(this); } } - diff --git a/Mage.Sets/src/mage/cards/h/HonorTheFallen.java b/Mage.Sets/src/mage/cards/h/HonorTheFallen.java index 855afa5cb4..f565f3250e 100644 --- a/Mage.Sets/src/mage/cards/h/HonorTheFallen.java +++ b/Mage.Sets/src/mage/cards/h/HonorTheFallen.java @@ -1,20 +1,21 @@ package mage.cards.h; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author L_J */ public final class HonorTheFallen extends CardImpl { @@ -34,48 +35,46 @@ public final class HonorTheFallen extends CardImpl { public HonorTheFallen copy() { return new HonorTheFallen(this); } - } class HonorTheFallenEffect extends OneShotEffect { - private static final FilterCreatureCard filter = new FilterCreatureCard(); - - public HonorTheFallenEffect() { + HonorTheFallenEffect() { super(Outcome.Detriment); staticText = "Exile all creature cards from all graveyards. You gain 1 life for each card exiled this way"; } - public HonorTheFallenEffect(final HonorTheFallenEffect effect) { + private HonorTheFallenEffect(final HonorTheFallenEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - int exiledCards = 0; - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - for (Card card : player.getGraveyard().getCards(game)) { - if (StaticFilters.FILTER_CARD_CREATURE.match(card, source.getSourceId(), controller.getId(), game)) { - if (card.moveToExile(null, "", source, game)) { - exiledCards++; - } - } - } - } - } - controller.gainLife(exiledCards, game, source); - return true; + if (controller == null) { + return false; } - return false; + Cards cards = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + cards.addAll(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)); + } + controller.moveCards(cards, Zone.EXILED, source, game); + int count = cards + .stream() + .map(game.getState()::getZone) + .map(Zone.EXILED::equals) + .mapToInt(x -> x ? 1 : 0) + .sum(); + controller.gainLife(count, game, source); + return true; } @Override public HonorTheFallenEffect copy() { return new HonorTheFallenEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/h/Hypnox.java b/Mage.Sets/src/mage/cards/h/Hypnox.java index ee5edcaa0a..70d7067d38 100644 --- a/Mage.Sets/src/mage/cards/h/Hypnox.java +++ b/Mage.Sets/src/mage/cards/h/Hypnox.java @@ -1,37 +1,36 @@ - package mage.cards.h; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.condition.common.CastFromHandSourcePermanentCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.ExileZone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.util.CardUtil; import mage.watchers.common.CastFromHandWatcher; +import java.util.UUID; + /** - * * @author L_J */ public final class Hypnox extends CardImpl { public Hypnox(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{8}{B}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{8}{B}{B}{B}"); this.subtype.add(SubType.NIGHTMARE); this.subtype.add(SubType.HORROR); this.power = new MageInt(8); @@ -41,10 +40,13 @@ public final class Hypnox extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Hypnox enters the battlefield, if you cast it from your hand, exile all cards from target opponent's hand. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new HypnoxExileEffect()); + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new HypnoxExileEffect()), + CastFromHandSourcePermanentCondition.instance, "When {this} enters the battlefield, " + + "if you cast it from your hand, exile all cards from target opponent's hand." + ); ability.addTarget(new TargetOpponent()); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, CastFromHandSourcePermanentCondition.instance, - "When {this} enters the battlefield, if you cast it from your hand, exile all cards from target opponent's hand."), new CastFromHandWatcher()); + this.addAbility(ability, new CastFromHandWatcher()); // When Hypnox leaves the battlefield, return the exiled cards to their owner's hand. this.addAbility(new LeavesBattlefieldTriggeredAbility(new HypnoxReturnEffect(), false)); @@ -61,45 +63,44 @@ public final class Hypnox extends CardImpl { } class HypnoxExileEffect extends OneShotEffect { + HypnoxExileEffect() { super(Outcome.Exile); staticText = "Exile all cards from target opponent's hand"; } - HypnoxExileEffect(final HypnoxExileEffect effect) { + private HypnoxExileEffect(final HypnoxExileEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - for (UUID cid : player.getHand().copy()) { - Card c = game.getCard(cid); - if (c != null) { - c.moveToExile(source.getSourceId(), "Hypnox", source, game); - } - } - return true; + Permanent permanent = source.getSourcePermanentOrLKI(game); + if (controller == null || player == null || permanent == null) { + return false; } - return false; + return controller.moveCardsToExile( + player.getHand().getCards(game), source, game, true, + CardUtil.getExileZoneId(game, source), permanent.getIdName() + ); } @Override public HypnoxExileEffect copy() { return new HypnoxExileEffect(this); } +} - } - class HypnoxReturnEffect extends OneShotEffect { - public HypnoxReturnEffect() { + HypnoxReturnEffect() { super(Outcome.ReturnToHand); this.staticText = "return the exiled cards to their owner's hand"; } - public HypnoxReturnEffect(final HypnoxReturnEffect effect) { + private HypnoxReturnEffect(final HypnoxReturnEffect effect) { super(effect); } @@ -111,13 +112,7 @@ class HypnoxReturnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - ExileZone exZone = game.getExile().getExileZone(source.getSourceId()); - if (exZone != null) { - return controller.moveCards(exZone.getCards(game), Zone.HAND, source, game); - } - return true; - } - return false; + ExileZone exZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + return controller != null && exZone != null && controller.moveCards(exZone, Zone.HAND, source, game); } }