diff --git a/Mage.Sets/src/mage/cards/r/RavenloftAdventurer.java b/Mage.Sets/src/mage/cards/r/RavenloftAdventurer.java new file mode 100644 index 00000000000..e9b55115914 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavenloftAdventurer.java @@ -0,0 +1,136 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CompletedDungeonCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.TakeTheInitiativeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; +import mage.watchers.common.CompletedDungeonWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RavenloftAdventurer extends CardImpl { + + public RavenloftAdventurer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When Ravenloft Adventurer enters the battlefield, you take the initiative. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TakeTheInitiativeEffect())); + + // If a creature an opponent controls would die, instead exile it and put a hit counter on it. + this.addAbility(new SimpleStaticAbility(new RavenloftAdventurerReplacementEffect())); + + // Whenever Ravenloft Adventurer attacks, if you've completed a dungeon, defending player loses 1 life for each card they own in exile with a hit counter on it. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility( + new RavenloftAdventurerLifeEffect(), false, "", SetTargetPointer.PLAYER + ), CompletedDungeonCondition.instance, "Whenever {this} attacks, if you've completed a dungeon, " + + "defending player loses 1 life for each card they own in exile with a hit counter on it." + ).addHint(CompletedDungeonCondition.getHint()), new CompletedDungeonWatcher()); + } + + private RavenloftAdventurer(final RavenloftAdventurer card) { + super(card); + } + + @Override + public RavenloftAdventurer copy() { + return new RavenloftAdventurer(this); + } +} + +class RavenloftAdventurerReplacementEffect extends ReplacementEffectImpl { + + RavenloftAdventurerReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + staticText = "if a creature an opponent controls would die, instead exile it and put a hit counter on it"; + } + + private RavenloftAdventurerReplacementEffect(final RavenloftAdventurerReplacementEffect effect) { + super(effect); + } + + @Override + public RavenloftAdventurerReplacementEffect copy() { + return new RavenloftAdventurerReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent permanent = ((ZoneChangeEvent) event).getTarget(); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || permanent == null + || !controller.hasOpponent(permanent.getControllerId(), game)) { + return false; + } + + return CardUtil.moveCardWithCounter(game, source, controller, permanent, Zone.EXILED, CounterType.HIT.createInstance()); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + ZoneChangeEvent zce = (ZoneChangeEvent) event; + return zce.isDiesEvent() && zce.getTarget().isCreature(game); + } +} + +class RavenloftAdventurerLifeEffect extends OneShotEffect { + + RavenloftAdventurerLifeEffect() { + super(Outcome.Benefit); + } + + private RavenloftAdventurerLifeEffect(final RavenloftAdventurerLifeEffect effect) { + super(effect); + } + + @Override + public RavenloftAdventurerLifeEffect copy() { + return new RavenloftAdventurerLifeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (player == null) { + return false; + } + int count = game + .getExile() + .getAllCards(game, player.getId()) + .stream() + .filter(card -> card.getCounters(game).containsKey(CounterType.HIT)) + .mapToInt(x -> 1) + .sum(); + return count > 0 && player.loseLife(count, game, source, false) > 0; + } +} diff --git a/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java b/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java index ebe8690fc07..0456171985c 100644 --- a/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java +++ b/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java @@ -472,6 +472,7 @@ public final class CommanderLegendsBattleForBaldursGate extends ExpansionSet { cards.add(new SetCardInfo("Raised by Giants", 250, Rarity.RARE, mage.cards.r.RaisedByGiants.class)); cards.add(new SetCardInfo("Raphael, Fiendish Savior", 292, Rarity.RARE, mage.cards.r.RaphaelFiendishSavior.class)); cards.add(new SetCardInfo("Rasaad yn Bashir", 37, Rarity.UNCOMMON, mage.cards.r.RasaadYnBashir.class)); + cards.add(new SetCardInfo("Ravenloft Adventurer", 142, Rarity.RARE, mage.cards.r.RavenloftAdventurer.class)); cards.add(new SetCardInfo("Ravenous Chupacabra", 770, Rarity.UNCOMMON, mage.cards.r.RavenousChupacabra.class)); cards.add(new SetCardInfo("Reckless Barbarian", 193, Rarity.COMMON, mage.cards.r.RecklessBarbarian.class)); cards.add(new SetCardInfo("Recruitment Drive", 38, Rarity.COMMON, mage.cards.r.RecruitmentDrive.class));