From 96092d84bc9c11ec1a5340872a883642dcf8d303 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 1 Nov 2020 16:30:07 -0500 Subject: [PATCH] [CMR] Implemented Jeska, Thrice Reborn --- Mage.Sets/src/mage/cards/c/ChandraNalaar.java | 46 +---- .../src/mage/cards/j/JeskaThriceReborn.java | 157 ++++++++++++++++++ Mage.Sets/src/mage/sets/CommanderLegends.java | 1 + .../dynamicvalue/common/GetXLoyaltyValue.java | 40 +++++ .../src/main/java/mage/constants/SubType.java | 1 + 5 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/j/JeskaThriceReborn.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXLoyaltyValue.java diff --git a/Mage.Sets/src/mage/cards/c/ChandraNalaar.java b/Mage.Sets/src/mage/cards/c/ChandraNalaar.java index fe44aa90a4..07769fef21 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraNalaar.java +++ b/Mage.Sets/src/mage/cards/c/ChandraNalaar.java @@ -1,14 +1,9 @@ package mage.cards.c; -import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.common.PayVariableLoyaltyCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; +import mage.abilities.dynamicvalue.common.GetXLoyaltyValue; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageTargetEffect; @@ -18,12 +13,12 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetPlayerOrPlaneswalker; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com, nantuko */ public final class ChandraNalaar extends CardImpl { @@ -41,7 +36,7 @@ public final class ChandraNalaar extends CardImpl { this.addAbility(ability1); // -X: Chandra Nalaar deals X damage to target creature. - LoyaltyAbility ability2 = new LoyaltyAbility(new DamageTargetEffect(ChandraNalaarXValue.getDefault())); + LoyaltyAbility ability2 = new LoyaltyAbility(new DamageTargetEffect(GetXLoyaltyValue.instance)); ability2.addTarget(new TargetCreaturePermanent()); this.addAbility(ability2); @@ -66,36 +61,3 @@ public final class ChandraNalaar extends CardImpl { } } -class ChandraNalaarXValue implements DynamicValue { - - private static final ChandraNalaarXValue defaultValue = new ChandraNalaarXValue(); - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for (Cost cost : sourceAbility.getCosts()) { - if (cost instanceof PayVariableLoyaltyCost) { - return ((PayVariableLoyaltyCost) cost).getAmount(); - } - } - return 0; - } - - @Override - public DynamicValue copy() { - return defaultValue; - } - - @Override - public String getMessage() { - return ""; - } - - @Override - public String toString() { - return "X"; - } - - public static ChandraNalaarXValue getDefault() { - return defaultValue; - } -} diff --git a/Mage.Sets/src/mage/cards/j/JeskaThriceReborn.java b/Mage.Sets/src/mage/cards/j/JeskaThriceReborn.java new file mode 100644 index 0000000000..cf846c6ca1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JeskaThriceReborn.java @@ -0,0 +1,157 @@ +package mage.cards.j; + +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.GetXLoyaltyValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.PartnerAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.DamagePlayerEvent; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; +import mage.watchers.common.CommanderPlaysCountWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JeskaThriceReborn extends CardImpl { + + public JeskaThriceReborn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.JESKA); + + // Jeska, Thrice Reborn enters the battlefield with a loyalty counter on it for each time you've cast a commander from the command zone this game. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect( + CounterType.LOYALTY.createInstance(0), JeskaThriceRebornValue.instance, false + ), "with a loyalty counter on it for each time " + + "you've cast a commander from the command zone this game" + ).addHint(JeskaThriceRebornValue.getHint()), new CommanderPlaysCountWatcher()); + + // +0: Choose target creature. Until your next turn, if that creature would deal combat damage to one of your opponents, it deals triple that damage to that player instead. + Ability ability = new LoyaltyAbility(new JeskaThriceRebornEffect(), 0); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // −X: Jeska, Thrice Reborn deals X damage to each of up to three targets. + ability = new LoyaltyAbility(new DamageTargetEffect(GetXLoyaltyValue.instance) + .setText("{this} deals X damage to each of up to three targets")); + ability.addTarget(new TargetAnyTarget(0, 3)); + this.addAbility(ability); + + // Jeska, Thrice Reborn can be your commander. + this.addAbility(CanBeYourCommanderAbility.getInstance()); + + // Partner + this.addAbility(PartnerAbility.getInstance()); + } + + private JeskaThriceReborn(final JeskaThriceReborn card) { + super(card); + } + + @Override + public JeskaThriceReborn copy() { + return new JeskaThriceReborn(this); + } +} + +enum JeskaThriceRebornValue implements DynamicValue { + instance; + private static final Hint hint = new ValueHint( + "Number of times you've cast a commander this turn", instance + ); + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Player player = game.getPlayer(sourceAbility.getControllerId()); + if (player == null) { + return 0; + } + CommanderPlaysCountWatcher watcher = game.getState().getWatcher(CommanderPlaysCountWatcher.class); + return watcher == null ? 0 : game + .getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER) + .stream() + .mapToInt(watcher::getPlaysCount) + .sum(); + } + + @Override + public JeskaThriceRebornValue copy() { + return instance; + } + + @Override + public String getMessage() { + return ""; + } + + public static Hint getHint() { + return hint; + } +} + +class JeskaThriceRebornEffect extends ReplacementEffectImpl { + + JeskaThriceRebornEffect() { + super(Duration.UntilYourNextTurn, Outcome.Damage); + staticText = "choose target creature. Until your next turn, " + + "if that creature would deal combat damage to one of your opponents, " + + "it deals triple that damage to that player instead"; + } + + private JeskaThriceRebornEffect(final JeskaThriceRebornEffect effect) { + super(effect); + } + + @Override + public JeskaThriceRebornEffect copy() { + return new JeskaThriceRebornEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!((DamagePlayerEvent) event).isCombatDamage() + || !event.getSourceId().equals(targetPointer.getFirst(game, source))) { + return false; + } + Player player = game.getPlayer(source.getControllerId()); + return player != null && player.hasOpponent(event.getTargetId(), game); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int amount = event.getAmount(); + event.setAmount(CardUtil.addWithOverflowCheck(amount, event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(amount, event.getAmount())); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/CommanderLegends.java b/Mage.Sets/src/mage/sets/CommanderLegends.java index fe74e38736..b46342f350 100644 --- a/Mage.Sets/src/mage/sets/CommanderLegends.java +++ b/Mage.Sets/src/mage/sets/CommanderLegends.java @@ -95,6 +95,7 @@ public final class CommanderLegends extends ExpansionSet { cards.add(new SetCardInfo("Inspiring Roar", 23, Rarity.COMMON, mage.cards.i.InspiringRoar.class)); cards.add(new SetCardInfo("Intangible Virtue", 24, Rarity.UNCOMMON, mage.cards.i.IntangibleVirtue.class)); cards.add(new SetCardInfo("Interpret the Signs", 75, Rarity.UNCOMMON, mage.cards.i.InterpretTheSigns.class)); + cards.add(new SetCardInfo("Jeska, Thrice Reborn", 186, Rarity.MYTHIC, mage.cards.j.JeskaThriceReborn.class)); cards.add(new SetCardInfo("Jeweled Lotus", 319, Rarity.MYTHIC, mage.cards.j.JeweledLotus.class)); cards.add(new SetCardInfo("Kamahl, Heart of Krosa", 237, Rarity.MYTHIC, mage.cards.k.KamahlHeartOfKrosa.class)); cards.add(new SetCardInfo("Kediss, Emberclaw Familiar", 188, Rarity.UNCOMMON, mage.cards.k.KedissEmberclawFamiliar.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXLoyaltyValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXLoyaltyValue.java new file mode 100644 index 0000000000..e72a347283 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXLoyaltyValue.java @@ -0,0 +1,40 @@ +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayVariableLoyaltyCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum GetXLoyaltyValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + for (Cost cost : sourceAbility.getCosts()) { + if (cost instanceof PayVariableLoyaltyCost) { + return ((PayVariableLoyaltyCost) cost).getAmount(); + } + } + return 0; + } + + @Override + public GetXLoyaltyValue copy() { + return instance; + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return ""; + } +} diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 48b90a1cf3..4682c8bda6 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -405,6 +405,7 @@ public enum SubType { GIDEON("Gideon", SubTypeSet.PlaneswalkerType), HUATLI("Huatli", SubTypeSet.PlaneswalkerType), JACE("Jace", SubTypeSet.PlaneswalkerType), + JESKA("Jeska", SubTypeSet.PlaneswalkerType), KARN("Karn", SubTypeSet.PlaneswalkerType), KASMINA("Kasmina", SubTypeSet.PlaneswalkerType), KAYA("Kaya", SubTypeSet.PlaneswalkerType),