diff --git a/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java b/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java new file mode 100644 index 00000000000..96e52bf32c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java @@ -0,0 +1,112 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.DiesOneOrMoreTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.*; +import mage.constants.*; +import mage.counters.CounterType; +import mage.counters.Counters; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RinoaAngelWing extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("attacking creatures you control"); + + static { + filter.add(AttackingPredicate.instance); + } + + public RinoaAngelWing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.REBEL); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // At the beginning of combat on your turn, creatures you control with flying get +1/+1 and gain vigilance until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new BoostControlledEffect( + 1, 1, Duration.EndOfTurn, StaticFilters.FILTER_CREATURE_FLYING + ).setText("creatures you control with flying get +1/+1")); + ability.addEffect(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_CREATURE_FLYING + ).setText("and gain vigilance until end of turn")); + this.addAbility(ability); + + // Whenever one or more attacking creatures you control die, you may return one of them to the battlefield tapped under its owner's control with a flying counter on it. Do this only once each turn. + this.addAbility(new DiesOneOrMoreTriggeredAbility( + new RinoaAngelWingEffect(), filter, true, true + ).setDoOnlyOnceEachTurn(true)); + } + + private RinoaAngelWing(final RinoaAngelWing card) { + super(card); + } + + @Override + public RinoaAngelWing copy() { + return new RinoaAngelWing(this); + } +} + +class RinoaAngelWingEffect extends OneShotEffect { + + RinoaAngelWingEffect() { + super(Outcome.Benefit); + staticText = "return one of them to the battlefield tapped " + + "under its owner's control with a flying counter on it"; + } + + private RinoaAngelWingEffect(final RinoaAngelWingEffect effect) { + super(effect); + } + + @Override + public RinoaAngelWingEffect copy() { + return new RinoaAngelWingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source)); + TargetCard target = new TargetCard(0, 1, Zone.ALL, StaticFilters.FILTER_CARD); + target.withNotTarget(true); + player.choose(Outcome.PutCreatureInPlay, cards, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + game.setEnterWithCounters(card.getId(), new Counters(CounterType.FLYING.createInstance())); + player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); + if (CardUtil.getPermanentFromCardPutToBattlefield(card, game) != null) { + return true; + } + } + TriggeredAbility.clearDidThisTurn(source, game); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java index d569cba84e5..f5f147f867f 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java +++ b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java @@ -320,6 +320,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 145, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 41, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 468, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rinoa, Angel Wing", 450, Rarity.RARE, mage.cards.r.RinoaAngelWing.class)); cards.add(new SetCardInfo("Rise of the Dark Realms", 283, Rarity.MYTHIC, mage.cards.r.RiseOfTheDarkRealms.class)); cards.add(new SetCardInfo("Rite of Replication", 270, Rarity.RARE, mage.cards.r.RiteOfReplication.class)); cards.add(new SetCardInfo("Rogue's Passage", 415, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java index a537a79f359..db0a74f26fb 100644 --- a/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java @@ -5,23 +5,34 @@ import mage.abilities.BatchTriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeBatchEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTargets; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; /** * @author Susucr */ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { - private final FilterCreaturePermanent filter; + private final FilterPermanent filter; + private final boolean setTargetPointer; - public DiesOneOrMoreTriggeredAbility(Effect effect, FilterCreaturePermanent filter, boolean optional) { + public DiesOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) { + this(effect, filter, optional, false); + } + + public DiesOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); this.filter = filter; + this.setTargetPointer = setTargetPointer; this.setTriggerPhrase("Whenever one or more " + filter.getMessage() + " die, "); setLeavesTheBattlefieldTrigger(true); } @@ -29,6 +40,7 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen private DiesOneOrMoreTriggeredAbility(final DiesOneOrMoreTriggeredAbility ability) { super(ability); this.filter = ability.filter; + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -52,7 +64,21 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen @Override public boolean checkTrigger(GameEvent event, Game game) { - return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); + List events = getFilteredEvents((ZoneChangeBatchEvent) event, game); + if (events.isEmpty()) { + return false; + } + if (setTargetPointer) { + this.getAllEffects().setTargetPointer(new FixedTargets( + events.stream() + .map(GameEvent::getTargetId) + .map(game::getCard) + .filter(Objects::nonNull) + .collect(Collectors.toSet()), + game + )); + } + return true; } @Override