refactored zone changes, letters E and F

simplified Enduring Renewal and Firemind's Foresight, fixed Faith's Reward and Fell Shepherd counting cards which had left and re-entered graveyards
This commit is contained in:
Evan Kranzler 2021-02-24 15:41:20 -05:00
parent 746d5eef3b
commit 756ca46718
10 changed files with 251 additions and 322 deletions

View file

@ -1,25 +1,21 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.continuous.PlayWithHandRevealedEffect;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author anonymous
*/
@ -31,15 +27,16 @@ public final class EnduringRenewal extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
// Play with your hand revealed.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithHandRevealedEffect()));
this.addAbility(new SimpleStaticAbility(new PlayWithHandRevealedEffect(TargetController.YOU)));
// If you would draw a card, reveal the top card of your library instead. If it's a creature card, put it into your graveyard. Otherwise, draw a card.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EnduringRenewalReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new EnduringRenewalReplacementEffect()));
// Whenever a creature is put into your graveyard from the battlefield, return it to your hand.
Effect effect = new ReturnFromGraveyardToHandTargetEffect();
effect.setText("return it to your hand");
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(effect, false, filter, true, true));
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(
new ReturnFromGraveyardToHandTargetEffect().setText("return it to your hand"),
false, filter, true, true
));
}
private EnduringRenewal(final EnduringRenewal card) {
@ -54,12 +51,13 @@ public final class EnduringRenewal extends CardImpl {
class EnduringRenewalReplacementEffect extends ReplacementEffectImpl {
public EnduringRenewalReplacementEffect() {
EnduringRenewalReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "If you would draw a card, reveal the top card of your library instead. If it's a creature card, put it into your graveyard. Otherwise, draw a card";
staticText = "If you would draw a card, reveal the top card of your library instead. " +
"If it's a creature card, put it into your graveyard. Otherwise, draw a card";
}
public EnduringRenewalReplacementEffect(final EnduringRenewalReplacementEffect effect) {
private EnduringRenewalReplacementEffect(final EnduringRenewalReplacementEffect effect) {
super(effect);
}
@ -80,18 +78,18 @@ class EnduringRenewalReplacementEffect extends ReplacementEffectImpl {
return false;
}
Card card = controller.getLibrary().getFromTop(game);
if (card != null) {
Cards cards = new CardsImpl(card);
controller.revealCards("Top card of " + controller.getName() + "'s library", cards, game);
if (card.isCreature()) {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
} else {
// This is still replacing the draw, so we still return true
controller.drawCards(1, source, game, event);
}
return true;
if (card == null) {
return false;
}
return false;
Cards cards = new CardsImpl(card);
controller.revealCards("Top card of " + controller.getName() + "'s library", cards, game);
if (card.isCreature()) {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
} else {
// This is still replacing the draw, so we still return true
controller.drawCards(1, source, game, event);
}
return true;
}
@Override
@ -104,62 +102,3 @@ class EnduringRenewalReplacementEffect extends ReplacementEffectImpl {
return event.getPlayerId().equals(source.getControllerId());
}
}
class PlayWithHandRevealedEffect extends ContinuousEffectImpl {
public PlayWithHandRevealedEffect() {
super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Detriment);
staticText = "Play with your hand revealed";
}
public PlayWithHandRevealedEffect(final PlayWithHandRevealedEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
controller.revealCards(controller.getName(), controller.getHand(), game, false);
return true;
}
return false;
}
@Override
public PlayWithHandRevealedEffect copy() {
return new PlayWithHandRevealedEffect(this);
}
}
class EnduringRenewalEffect extends OneShotEffect {
public EnduringRenewalEffect() {
super(Outcome.ReturnToHand);
staticText = "return it to your hand";
}
public EnduringRenewalEffect(final EnduringRenewalEffect effect) {
super(effect);
}
@Override
public EnduringRenewalEffect copy() {
return new EnduringRenewalEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID creatureId = (UUID) getValue("returningCreature");
Permanent creature = game.getPermanent(creatureId);
if (creature != null) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
creature.moveToZone(Zone.HAND, source, game, false);
}
return true;
}
return false;
}
}

View file

@ -1,10 +1,5 @@
package mage.cards.e;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@ -20,14 +15,18 @@ import mage.target.TargetCard;
import mage.target.common.TargetOpponent;
import mage.util.GameLog;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class EpiphanyAtTheDrownyard extends CardImpl {
public EpiphanyAtTheDrownyard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}");
// Reveal the top X plus one cards of your library and separate them into two piles. An opponent chooses one of those piles. Put that pile into your hand and the other into your graveyard.
this.getSpellAbility().addEffect(new EpiphanyAtTheDrownyardEffect());
@ -46,12 +45,12 @@ public final class EpiphanyAtTheDrownyard extends CardImpl {
class EpiphanyAtTheDrownyardEffect extends OneShotEffect {
public EpiphanyAtTheDrownyardEffect() {
EpiphanyAtTheDrownyardEffect() {
super(Outcome.DrawCard);
this.staticText = "Reveal the top X plus one cards of your library and separate them into two piles. An opponent chooses one of those piles. Put that pile into your hand and the other into your graveyard";
}
public EpiphanyAtTheDrownyardEffect(final EpiphanyAtTheDrownyardEffect effect) {
private EpiphanyAtTheDrownyardEffect(final EpiphanyAtTheDrownyardEffect effect) {
super(effect);
}
@ -124,9 +123,9 @@ class EpiphanyAtTheDrownyardEffect extends OneShotEffect {
if (i < pile1CardsIds.size()) {
sb.append(", ");
}
card.moveToZone(pile1Zone, source, game, false);
}
}
controller.moveCards(new CardsImpl(pile1CardsIds), pile1Zone, source, game);
game.informPlayers(sb.toString());
sb = new StringBuilder(sourceObject.getLogName() + ": Pile 2, going to ").append(pile2Zone == Zone.HAND ? "Hand" : "Graveyard").append(':');
@ -139,9 +138,9 @@ class EpiphanyAtTheDrownyardEffect extends OneShotEffect {
if (i < pile2CardsIds.size()) {
sb.append(", ");
}
card.moveToZone(pile2Zone, source, game, false);
}
}
controller.moveCards(new CardsImpl(pile2CardsIds), pile2Zone, source, game);
game.informPlayers(sb.toString());
}

View file

@ -17,6 +17,7 @@ import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledEnchantmentPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.functions.CopyApplier;
import java.util.UUID;
@ -68,8 +69,7 @@ class EstridsInvocationEffect extends OneShotEffect {
EstridsInvocationEffect() {
super(Outcome.Neutral);
this.staticText = "you may exile this enchantment. "
+ "If you do, return it to the battlefield under its owner's control";
this.staticText = "exile this enchantment. If you do, return it to the battlefield under its owner's control";
}
private EstridsInvocationEffect(final EstridsInvocationEffect effect) {
@ -83,15 +83,14 @@ class EstridsInvocationEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
if (permanent.moveToExile(source.getSourceId(), "Estrid's Invocation", source, game)) {
Card card = game.getExile().getCard(source.getSourceId(), game);
if (card != null) {
return card.moveToZone(Zone.BATTLEFIELD, source, game, false);
}
}
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || player == null) {
return false;
}
return false;
Card card = permanent.getMainCard();
player.moveCards(card, Zone.EXILED, source, game);
player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
return true;
}
}

View file

@ -1,12 +1,11 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.AuraAttachedCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
@ -16,18 +15,22 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.card.AuraCardCanAttachToPermanentId;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import java.util.UUID;
/**
* @author jeffwadsworth
*/
public final class Evershrike extends CardImpl {
private static final DynamicValue amount = new AuraAttachedCount(2);
public Evershrike(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/B}{W/B}");
this.subtype.add(SubType.ELEMENTAL);
@ -40,12 +43,10 @@ public final class Evershrike extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Evershrike gets +2/+2 for each Aura attached to it.
AuraAttachedCount amount = new AuraAttachedCount(2);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield)));
// {X}{WB}{WB}: Return Evershrike from your graveyard to the battlefield. You may put an Aura card with converted mana cost X or less from your hand onto the battlefield attached to it. If you don't, exile Evershrike.
this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new EvershrikeEffect(), new ManaCostsImpl("{X}{W/B}{W/B}")));
}
private Evershrike(final Evershrike card) {
@ -60,12 +61,14 @@ public final class Evershrike extends CardImpl {
class EvershrikeEffect extends OneShotEffect {
public EvershrikeEffect() {
EvershrikeEffect() {
super(Outcome.Benefit);
staticText = "Return {this} from your graveyard to the battlefield. You may put an Aura card with converted mana cost X or less from your hand onto the battlefield attached to it. If you don't, exile {this}";
staticText = "Return {this} from your graveyard to the battlefield. " +
"You may put an Aura card with converted mana cost X or less from your hand " +
"onto the battlefield attached to it. If you don't, exile {this}";
}
public EvershrikeEffect(final EvershrikeEffect effect) {
private EvershrikeEffect(final EvershrikeEffect effect) {
super(effect);
}
@ -73,40 +76,42 @@ class EvershrikeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Card evershrikeCard = game.getCard(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && evershrikeCard != null) {
if (evershrikeCard.moveToZone(Zone.BATTLEFIELD, source, game, false)) {
int xAmount = source.getManaCostsToPay().getX() + 1;
Permanent evershrikePermanent = game.getPermanent(source.getSourceId());
if (evershrikePermanent == null) {
return false;
}
boolean exileSource = true;
FilterCard filterAuraCard = new FilterCard("Aura card with converted mana cost X or less from your hand");
filterAuraCard.add(CardType.ENCHANTMENT.getPredicate());
filterAuraCard.add(SubType.AURA.getPredicate());
filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId()));
filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xAmount));
int count = controller.getHand().count(filterAuraCard, game);
if (count > 0 && controller.chooseUse(Outcome.Benefit, "Put an Aura card from your hand onto the battlefield attached to " + evershrikeCard.getIdName() + "?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard);
if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget());
if (aura != null) {
game.getState().setValue("attachTo:" + aura.getId(), evershrikePermanent);
if (controller.moveCards(aura, Zone.BATTLEFIELD, source, game)) {
evershrikePermanent.addAttachment(aura.getId(), source, game);
}
exileSource = false;
}
if (controller == null || evershrikeCard == null) {
return false;
}
int xAmount = source.getManaCostsToPay().getX();
controller.moveCards(evershrikeCard, Zone.BATTLEFIELD, source, game);
Permanent evershrikePermanent = game.getPermanent(evershrikeCard.getId());
if (evershrikePermanent == null) {
if (game.getState().getZone(evershrikeCard.getId()) != Zone.EXILED) {
controller.moveCards(evershrikeCard, Zone.EXILED, source, game);
}
return false;
}
boolean exileSource = true;
FilterCard filterAuraCard = new FilterCard("Aura card with converted mana cost X or less from your hand");
filterAuraCard.add(CardType.ENCHANTMENT.getPredicate());
filterAuraCard.add(SubType.AURA.getPredicate());
filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId()));
filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xAmount + 1));
int count = controller.getHand().count(filterAuraCard, game);
if (count > 0 && controller.chooseUse(Outcome.Benefit, "Put an Aura card from your hand onto the battlefield attached to " + evershrikeCard.getIdName() + "?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard);
if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget());
if (aura != null) {
game.getState().setValue("attachTo:" + aura.getId(), evershrikePermanent);
if (controller.moveCards(aura, Zone.BATTLEFIELD, source, game)) {
evershrikePermanent.addAttachment(aura.getId(), source, game);
}
exileSource = false;
}
if (exileSource) {
controller.moveCards(evershrikeCard, Zone.EXILED, source, game);
}
return true;
}
}
return false;
if (exileSource) {
controller.moveCards(evershrikeCard, Zone.EXILED, source, game);
}
return true;
}
@Override

View file

@ -1,10 +1,5 @@
package mage.cards.f;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@ -19,6 +14,11 @@ import mage.target.Target;
import mage.target.TargetCard;
import mage.target.common.TargetOpponent;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* @author North
*/
@ -43,12 +43,12 @@ public final class FactOrFiction extends CardImpl {
class FactOrFictionEffect extends OneShotEffect {
public FactOrFictionEffect() {
FactOrFictionEffect() {
super(Outcome.DrawCard);
this.staticText = "Reveal the top five cards of your library. An opponent separates those cards into two piles. Put one pile into your hand and the other into your graveyard";
}
public FactOrFictionEffect(final FactOrFictionEffect effect) {
private FactOrFictionEffect(final FactOrFictionEffect effect) {
super(effect);
}
@ -110,8 +110,10 @@ class FactOrFictionEffect extends OneShotEffect {
if (i < pile1.size()) {
sb.append(", ");
}
card.moveToZone(pile1Zone, source, game, false);
}
cards.clear();
cards.addAll(pile1);
controller.moveCards(cards, pile1Zone, source, game);
game.informPlayers(sb.toString());
sb = new StringBuilder("Pile 2, going to ").append(pile2Zone == Zone.HAND ? "Hand" : "Graveyard").append(':');
@ -122,8 +124,10 @@ class FactOrFictionEffect extends OneShotEffect {
if (i < pile2.size()) {
sb.append(", ");
}
card.moveToZone(pile2Zone, source, game, false);
}
cards.clear();
cards.addAll(pile2);
controller.moveCards(cards, pile2Zone, source, game);
game.informPlayers(sb.toString());
}

View file

@ -1,18 +1,15 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.keyword.FlyingAbility;
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.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
@ -21,14 +18,15 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class FaerieImpostor extends CardImpl {
public FaerieImpostor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}");
this.subtype.add(SubType.FAERIE);
this.subtype.add(SubType.ROGUE);
@ -66,36 +64,32 @@ class FaerieImpostorEffect extends OneShotEffect {
staticText = effectText;
}
FaerieImpostorEffect(FaerieImpostorEffect effect) {
private FaerieImpostorEffect(FaerieImpostorEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
boolean targetChosen = false;
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.chooseUse(outcome, "Return another creature you control to its owner's hand?", source, game)) {
controller.chooseTarget(Outcome.ReturnToHand, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
targetChosen = true;
permanent.moveToZone(Zone.HAND, source, game, false);
}
}
if (!targetChosen) {
new SacrificeSourceEffect().apply(game, source);
}
return true;
if (controller == null) {
return false;
}
return false;
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)
&& controller.chooseUse(outcome, "Return another creature you control to its owner's hand?", source, game)) {
controller.chooseTarget(Outcome.ReturnToHand, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
controller.moveCards(permanent, Zone.HAND, source, game);
return true;
}
}
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
return permanent != null && permanent.sacrifice(source, game);
}
@Override
public FaerieImpostorEffect copy() {
return new FaerieImpostorEffect(this);
}
}

View file

@ -1,11 +1,13 @@
package mage.cards.f;
import mage.MageObject;
import mage.MageObjectReference;
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.WatcherScope;
@ -13,21 +15,21 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
*
* @author Loki
*/
public final class FaithsReward extends CardImpl {
public FaithsReward(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}");
// Return to the battlefield all permanent cards in your graveyard that were put there from the battlefield this turn.
this.getSpellAbility().addEffect(new FaithsRewardEffect());
@ -51,23 +53,18 @@ class FaithsRewardEffect extends OneShotEffect {
staticText = "Return to the battlefield all permanent cards in your graveyard that were put there from the battlefield this turn";
}
FaithsRewardEffect(final FaithsRewardEffect effect) {
private FaithsRewardEffect(final FaithsRewardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
FaithsRewardWatcher watcher = game.getState().getWatcher(FaithsRewardWatcher.class);
if (watcher != null) {
for (UUID id : watcher.getCards()) {
Card c = game.getCard(id);
if (c != null && c.isOwnedBy(source.getControllerId()) && game.getState().getZone(id) == Zone.GRAVEYARD) {
c.moveToZone(Zone.BATTLEFIELD, source, game, false);
}
}
return true;
if (player == null || watcher == null) {
return false;
}
return false;
return player.moveCards(watcher.getCards(source.getControllerId(), game), Zone.BATTLEFIELD, source, game);
}
@Override
@ -77,26 +74,34 @@ class FaithsRewardEffect extends OneShotEffect {
}
class FaithsRewardWatcher extends Watcher {
private List<UUID> cards = new ArrayList<>();
public FaithsRewardWatcher() {
private final Set<MageObjectReference> morMap = new HashSet<>();
FaithsRewardWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).isDiesEvent()) {
cards.add(event.getTargetId());
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) {
morMap.add(new MageObjectReference(((ZoneChangeEvent) event).getTarget(), game));
}
}
public List<UUID> getCards(){
Cards getCards(UUID ownerId, Game game) {
Cards cards = new CardsImpl();
morMap.stream()
.map(m -> m.getCard(game))
.filter(Objects::nonNull)
.filter(MageObject::isPermanent)
.filter(c -> c.isOwnedBy(ownerId))
.forEach(cards::add);
return cards;
}
@Override
public void reset() {
super.reset();
cards.clear();
morMap.clear();
}
}

View file

@ -1,11 +1,8 @@
package mage.cards.f;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -13,21 +10,26 @@ import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.Watcher;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class FellShepherd extends CardImpl {
@ -43,8 +45,8 @@ public final class FellShepherd extends CardImpl {
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new FellShepherdEffect(), true), new FellShepherdWatcher());
// {B}, Sacrifice another creature: Target creature gets -2/-2 until end of turn.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{B}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false)));
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{B}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
@ -60,72 +62,62 @@ public final class FellShepherd extends CardImpl {
}
}
class FellShepherdWatcher extends Watcher {
private Set<UUID> creatureIds = new HashSet<>();
public FellShepherdWatcher() {
super(WatcherScope.PLAYER);
condition = true;
}
public Set<UUID> getCreaturesIds() {
return creatureIds;
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) {
MageObject card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (card != null && ((Card) card).isOwnedBy(this.controllerId) && card.isCreature()) {
creatureIds.add(card.getId());
}
}
}
@Override
public void reset() {
super.reset();
creatureIds.clear();
}
}
class FellShepherdEffect extends OneShotEffect {
public FellShepherdEffect() {
super(Outcome.ReturnToHand);
this.staticText = "return to your hand all creature cards that were put into your graveyard from the battlefield this turn";
FellShepherdEffect() {
super(Outcome.PutCardInPlay);
staticText = "return to your hand all creature cards that were put into your graveyard from the battlefield this turn";
}
public FellShepherdEffect(final FellShepherdEffect effect) {
private FellShepherdEffect(final FellShepherdEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
FellShepherdWatcher watcher = game.getState().getWatcher(FellShepherdWatcher.class);
if (player == null || watcher == null) {
return false;
}
return player.moveCards(watcher.getCards(source.getControllerId(), game), Zone.HAND, source, game);
}
@Override
public FellShepherdEffect copy() {
return new FellShepherdEffect(this);
}
}
class FellShepherdWatcher extends Watcher {
private final Set<MageObjectReference> morMap = new HashSet<>();
FellShepherdWatcher() {
super(WatcherScope.GAME);
}
@Override
public boolean apply(Game game, Ability source) {
FellShepherdWatcher watcher = game.getState().getWatcher(FellShepherdWatcher.class, source.getControllerId());
if (watcher != null) {
StringBuilder sb = new StringBuilder();
for (UUID creatureId : watcher.getCreaturesIds()) {
if (game.getState().getZone(creatureId) == Zone.GRAVEYARD) {
Card card = game.getCard(creatureId);
if (card != null) {
card.moveToZone(Zone.HAND, source, game, false);
sb.append(' ').append(card.getName());
}
}
}
if (sb.length() > 0) {
sb.insert(0, "Fell Shepherd - returning to hand:");
game.informPlayers(sb.toString());
}
return true;
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) {
morMap.add(new MageObjectReference(((ZoneChangeEvent) event).getTarget(), game));
}
return false;
}
Cards getCards(UUID ownerId, Game game) {
Cards cards = new CardsImpl();
morMap.stream()
.map(m -> m.getCard(game))
.filter(Objects::nonNull)
.filter(MageObject::isCreature)
.filter(c -> c.isOwnedBy(ownerId))
.forEach(cards::add);
return cards;
}
@Override
public void reset() {
super.reset();
morMap.clear();
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
@ -15,15 +13,17 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class FiremindsForesight extends CardImpl {
public FiremindsForesight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{U}{R}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{U}{R}");
// Search your library for an instant card with converted mana cost 3, reveal it,
// and put it into your hand. Then repeat this process for instant cards with
@ -41,14 +41,27 @@ public final class FiremindsForesight extends CardImpl {
}
}
class FiremindsForesightSearchEffect extends OneShotEffect {
class FiremindsForesightSearchEffect extends OneShotEffect {
public FiremindsForesightSearchEffect() {
super(Outcome.DrawCard);
staticText = "Search your library for an instant card with converted mana cost 3, reveal it, and put it into your hand. Then repeat this process for instant cards with converted mana costs 2 and 1. Then shuffle your library";
private static final Map<Integer, FilterCard> filterMap = new HashMap<>();
static {
for (int cmc = 3; cmc > 0; cmc--) {
FilterCard filter = new FilterCard("instant card with converted mana cost " + cmc);
filter.add(CardType.INSTANT.getPredicate());
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc));
filterMap.put(cmc, filter);
}
}
public FiremindsForesightSearchEffect(final FiremindsForesightSearchEffect effect) {
FiremindsForesightSearchEffect() {
super(Outcome.DrawCard);
staticText = "Search your library for an instant card with converted mana cost 3, " +
"reveal it, and put it into your hand. Then repeat this process " +
"for instant cards with converted mana costs 2 and 1. Then shuffle your library";
}
private FiremindsForesightSearchEffect(final FiremindsForesightSearchEffect effect) {
super(effect);
}
@ -60,41 +73,22 @@ class FiremindsForesightSearchEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (player == null || sourceCard == null) {
if (player == null) {
return false;
}
int cardsCount;
Cards cardToReveal = new CardsImpl();
Cards cardsInLibrary = new CardsImpl();
cardsInLibrary.addAll(player.getLibrary().getCards(game));
for (int cmc=3; cmc > 0; cmc--) {
FilterCard filter = new FilterCard("instant card with converted mana cost " + cmc);
filter.add(CardType.INSTANT.getPredicate());
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc));
cardsCount = cardsInLibrary.count(filter, game);
if (cardsCount > 0) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter);
if (player.searchLibrary(target, source, game)) {
for (UUID cardId: target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
card.moveToZone(Zone.HAND, source, game, false);
game.informPlayers(sourceCard.getName()+": " + player.getLogName() + " chose " + card.getName() );
cardsInLibrary.remove(card);
cardToReveal.add(card);
player.revealCards(sourceCard.getName(), cardToReveal, game);
}
}
}
} else {
player.lookAtCards(filter.getMessage(), cardsInLibrary, game);
for (int cmc = 3; cmc > 0; cmc--) {
TargetCardInLibrary target = new TargetCardInLibrary(filterMap.get(cmc));
player.searchLibrary(target, source, game);
Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
if (card == null) {
continue;
}
cardToReveal.clear();
cardToReveal.add(card);
player.revealCards(source, cardToReveal, game);
player.moveCards(cardToReveal, Zone.HAND, source, game);
}
player.shuffleLibrary(source, game);
return true;
}

View file

@ -1,7 +1,5 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -17,9 +15,11 @@ import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class FlickeringSpirit extends CardImpl {
@ -34,8 +34,7 @@ public final class FlickeringSpirit extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {3}{W}: Exile Flickering Spirit, then return it to the battlefield under its owner's control.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new FlickeringSpiritEffect(), new ManaCostsImpl("{3}{W}")));
this.addAbility(new SimpleActivatedAbility(new FlickeringSpiritEffect(), new ManaCostsImpl("{3}{W}")));
}
private FlickeringSpirit(final FlickeringSpirit card) {
@ -50,12 +49,12 @@ public final class FlickeringSpirit extends CardImpl {
class FlickeringSpiritEffect extends OneShotEffect {
public FlickeringSpiritEffect() {
FlickeringSpiritEffect() {
super(Outcome.Neutral);
this.staticText = "Exile {this}, then return it to the battlefield under its owner's control";
}
public FlickeringSpiritEffect(final FlickeringSpiritEffect effect) {
private FlickeringSpiritEffect(final FlickeringSpiritEffect effect) {
super(effect);
}
@ -66,15 +65,14 @@ class FlickeringSpiritEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
if (permanent.moveToExile(source.getSourceId(), "Flickering Spirit", source, game)) {
Card card = game.getExile().getCard(source.getSourceId(), game);
if (card != null) {
return card.moveToZone(Zone.BATTLEFIELD, source, game, false);
}
}
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || player == null) {
return false;
}
return false;
Card card = permanent.getMainCard();
player.moveCards(card, Zone.EXILED, source, game);
player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
return true;
}
}