From 99c50d041a53bf970552dde936f5e97825291691 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Mon, 9 Dec 2019 10:45:50 -0600 Subject: [PATCH 01/10] - Fixed #6079 --- Mage.Sets/src/mage/cards/b/BrimstoneVolley.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java index d58a4b1021a..ad202a03450 100644 --- a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java +++ b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java @@ -1,7 +1,5 @@ - package mage.cards.b; -import mage.abilities.condition.common.HellbentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; @@ -9,8 +7,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetAnyTarget; import mage.watchers.common.MorbidWatcher; - import java.util.UUID; +import mage.abilities.condition.common.MorbidCondition; /** * @author nantuko @@ -23,9 +21,9 @@ public final class BrimstoneVolley extends CardImpl { // Brimstone Volley deals 3 damage to any target. // Morbid — Brimstone Volley deals 5 damage to that creature or player instead if a creature died this turn. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetEffect(3), new DamageTargetEffect(5), HellbentCondition.instance, - "{this} deals 3 damage to any target." + - "
Morbid — {this} deals 5 damage instead if a creature died this turn." + new DamageTargetEffect(3), new DamageTargetEffect(5), MorbidCondition.instance, + "{this} deals 3 damage to any target." + + "
Morbid — {this} deals 5 damage instead if a creature died this turn." )); this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addWatcher(new MorbidWatcher()); From b2e4e950d0ec915a84282c76f6bfd042275f4752 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Mon, 9 Dec 2019 15:26:57 -0500 Subject: [PATCH 02/10] 6079 - Fixing conditional damage order, conditions (#6080) * 6079 - Fixing conditional damage order, conditions As of c482fad, a number of spells had their conditional damage reworded in oracle text. As a part of these changes, some of the spells had their order of effects inverted, with the damage after the condition was happening before the condition was met. In addition, Brimstone volley was changed from a Morbid condition to a Hellbent condition. This commit corrects those typos. * Update Mage.Sets/src/mage/cards/f/FirecannonBlast.java Co-Authored-By: Fenhl --- Mage.Sets/src/mage/cards/b/BrimstoneVolley.java | 8 ++++---- Mage.Sets/src/mage/cards/c/CacklingFlames.java | 2 +- Mage.Sets/src/mage/cards/f/FirecannonBlast.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java index ad202a03450..dfc42e7bc6f 100644 --- a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java +++ b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java @@ -1,5 +1,6 @@ package mage.cards.b; +import mage.abilities.condition.common.MorbidCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; @@ -8,7 +9,6 @@ import mage.constants.CardType; import mage.target.common.TargetAnyTarget; import mage.watchers.common.MorbidWatcher; import java.util.UUID; -import mage.abilities.condition.common.MorbidCondition; /** * @author nantuko @@ -21,9 +21,9 @@ public final class BrimstoneVolley extends CardImpl { // Brimstone Volley deals 3 damage to any target. // Morbid — Brimstone Volley deals 5 damage to that creature or player instead if a creature died this turn. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetEffect(3), new DamageTargetEffect(5), MorbidCondition.instance, - "{this} deals 3 damage to any target." - + "
Morbid — {this} deals 5 damage instead if a creature died this turn." + new DamageTargetEffect(5), new DamageTargetEffect(3), MorbidCondition.instance, + "{this} deals 3 damage to any target." + + "
Morbid — {this} deals 5 damage instead if a creature died this turn." )); this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addWatcher(new MorbidWatcher()); diff --git a/Mage.Sets/src/mage/cards/c/CacklingFlames.java b/Mage.Sets/src/mage/cards/c/CacklingFlames.java index 194036356c5..0bf4c194f62 100644 --- a/Mage.Sets/src/mage/cards/c/CacklingFlames.java +++ b/Mage.Sets/src/mage/cards/c/CacklingFlames.java @@ -21,7 +21,7 @@ public final class CacklingFlames extends CardImpl { // Cackling Flames deals 3 damage to any target. // Hellbent - Cackling Flames deals 5 damage to that creature or player instead if you have no cards in hand. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetEffect(3), new DamageTargetEffect(5), HellbentCondition.instance, + new DamageTargetEffect(5), new DamageTargetEffect(3), HellbentCondition.instance, "{this} deals 3 damage to any target
Hellbent " + "— {this} deals 5 damage instead if you have no cards in hand." )); diff --git a/Mage.Sets/src/mage/cards/f/FirecannonBlast.java b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java index 5f387877bee..ae1daf34610 100644 --- a/Mage.Sets/src/mage/cards/f/FirecannonBlast.java +++ b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java @@ -24,9 +24,9 @@ public final class FirecannonBlast extends CardImpl { // Firecannon Blast deals 3 damage to target creature. // Raid - Firecannon Blast deals 6 damage to that creature instead if you attacked with a creature this turn. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetEffect(3), new DamageTargetEffect(6), - new InvertCondition(RaidCondition.instance), + new DamageTargetEffect(3), + RaidCondition.instance, "{this} deals 3 damage to target creature.
Raid — {this} deals 6 damage instead if you attacked with a creature this turn")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addWatcher(new PlayerAttackedWatcher()); From ca22a7750a6a19952841c2747cf3a88431437020 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Tue, 10 Dec 2019 10:25:07 -0600 Subject: [PATCH 03/10] - Fixed #5925 and related issues. --- .../src/mage/cards/s/SidisiUndeadVizier.java | 2 +- .../ExploitCreatureTriggeredAbility.java | 18 +++++---- .../GodEternalDiesTriggeredAbility.java | 40 ++++++++++--------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java b/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java index 05a20269890..df384d65312 100644 --- a/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java +++ b/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java @@ -36,7 +36,7 @@ public final class SidisiUndeadVizier extends CardImpl { this.addAbility(new ExploitAbility()); // When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library. - this.addAbility(new ExploitCreatureTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCard("a card")), false, true), false)); + this.addAbility(new ExploitCreatureTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCard("card")), false, true), false)); } public SidisiUndeadVizier(final SidisiUndeadVizier card) { diff --git a/Mage/src/main/java/mage/abilities/common/ExploitCreatureTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ExploitCreatureTriggeredAbility.java index 753a2907169..75d32f71e9a 100644 --- a/Mage/src/main/java/mage/abilities/common/ExploitCreatureTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ExploitCreatureTriggeredAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.common; import mage.MageObject; @@ -8,6 +7,7 @@ import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** @@ -44,14 +44,18 @@ public class ExploitCreatureTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { - if (event.getTargetId().equals(getSourceId()) && event.getSourceId().equals(getSourceId())) { - if (!this.hasSourceObjectAbility(game, source, event)) { - return false; + Permanent sourcePermanent = null; + if (game.getState().getZone(getSourceId()) == Zone.BATTLEFIELD) { + sourcePermanent = game.getPermanent(getSourceId()); + } else { + if (game.getShortLivingLKI(getSourceId(), Zone.BATTLEFIELD)) { + sourcePermanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD); } - this.setControllerId(event.getPlayerId()); - return true; // if Exploits creature sacrifices itself, exploit triggers } - return super.isInUseableZone(game, source, event); + if (sourcePermanent == null) { + return false; + } + return hasSourceObjectAbility(game, sourcePermanent, event); } @Override diff --git a/Mage/src/main/java/mage/abilities/common/GodEternalDiesTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/GodEternalDiesTriggeredAbility.java index e59ceb25243..a300de53419 100644 --- a/Mage/src/main/java/mage/abilities/common/GodEternalDiesTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/GodEternalDiesTriggeredAbility.java @@ -1,5 +1,6 @@ package mage.abilities.common; +import mage.MageObject; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -17,8 +18,6 @@ import mage.players.Player; * @author TheElk801 */ public class GodEternalDiesTriggeredAbility extends TriggeredAbilityImpl { - - Boolean applied; public GodEternalDiesTriggeredAbility() { super(Zone.ALL, null, true); @@ -33,7 +32,7 @@ public class GodEternalDiesTriggeredAbility extends TriggeredAbilityImpl { if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; return zEvent.getFromZone() == Zone.BATTLEFIELD - && (zEvent.getToZone() == Zone.GRAVEYARD + && (zEvent.getToZone() == Zone.GRAVEYARD || zEvent.getToZone() == Zone.EXILED); } return false; @@ -41,24 +40,29 @@ public class GodEternalDiesTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - applied = false; ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getTargetId().equals(this.getSourceId())) { - Permanent permanent = game.getPermanentOrLKIBattlefield(this.getSourceId()); - // for cases where its triggered ability is removed, ex: Kasmina's Transmutation - if (permanent != null) { - for (Ability a : permanent.getAbilities()) { - if (a instanceof GodEternalDiesTriggeredAbility) { - applied = true; - } - } - } - if (applied) { this.getEffects().clear(); this.addEffect(new GodEternalEffect(new MageObjectReference(zEvent.getTarget(), game))); + return true; + } + return false; + } + + @Override + public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { + Permanent sourcePermanent = null; + if (game.getState().getZone(getSourceId()) == Zone.BATTLEFIELD) { + sourcePermanent = game.getPermanent(getSourceId()); + } else { + if (game.getShortLivingLKI(getSourceId(), Zone.BATTLEFIELD)) { + sourcePermanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD); } } - return applied; + if (sourcePermanent == null) { + return false; + } + return hasSourceObjectAbility(game, sourcePermanent, event); } @Override @@ -68,8 +72,8 @@ public class GodEternalDiesTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When {this} dies or is put into exile from the battlefield, " + - "you may put it into its owner's library third from the top."; + return "When {this} dies or is put into exile from the battlefield, " + + "you may put it into its owner's library third from the top."; } } @@ -104,4 +108,4 @@ class GodEternalEffect extends OneShotEffect { } return player.putCardOnTopXOfLibrary(card, game, source, 3); } -} \ No newline at end of file +} From dd68a1ba84b3a9eba28129919e540f3d92e00f72 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Tue, 10 Dec 2019 16:51:35 -0600 Subject: [PATCH 04/10] - Fixed #6084 --- Mage.Sets/src/mage/cards/d/DeadRingers.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DeadRingers.java b/Mage.Sets/src/mage/cards/d/DeadRingers.java index 476e4578cb5..e07ca86f513 100644 --- a/Mage.Sets/src/mage/cards/d/DeadRingers.java +++ b/Mage.Sets/src/mage/cards/d/DeadRingers.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.UUID; @@ -29,7 +28,7 @@ public final class DeadRingers extends CardImpl { } public DeadRingers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // Destroy two target nonblack creatures unless either one is a color the other isn't. They can't be regenerated. this.getSpellAbility().addEffect(new DeadRingersEffect()); @@ -65,10 +64,15 @@ class DeadRingersEffect extends DestroyTargetEffect { @Override public boolean apply(Game game, Ability source) { Target target = source.getTargets().get(0); - Permanent first = game.getPermanentOrLKIBattlefield(target.getTargets().get(0)); - Permanent second = game.getPermanentOrLKIBattlefield(target.getTargets().get(1)); - if(first != null && second != null && first.getColor(game).equals(second.getColor(game))) { - return super.apply(game, source); + if (target != null + && target.getTargets().size() > 1) { + Permanent first = game.getPermanentOrLKIBattlefield(target.getTargets().get(0)); + Permanent second = game.getPermanentOrLKIBattlefield(target.getTargets().get(1)); + if (first != null + && second != null + && first.getColor(game).equals(second.getColor(game))) { + return super.apply(game, source); + } } return false; } From 6b5a9846b984ccff54693f6666d95154ecab352b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 11 Dec 2019 04:40:07 +0400 Subject: [PATCH 05/10] Fixed rules generation --- Mage/src/main/java/mage/cards/CardImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index d903a30b0b3..6e5d5dc589c 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -230,7 +230,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { @Override public List getRules() { try { - return abilities.getRules(this.getName()); + return getAbilities().getRules(this.getName()); } catch (Exception e) { logger.info("Exception in rules generation for card: " + this.getName(), e); } From c6dd9a26210feeac6297feb24a4b4fa55ba6112b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 11 Dec 2019 04:40:52 +0400 Subject: [PATCH 06/10] * Master Splicer - fixed text; --- Mage.Sets/src/mage/cards/m/MasterSplicer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterSplicer.java b/Mage.Sets/src/mage/cards/m/MasterSplicer.java index 44a09f47874..f9d330160b7 100644 --- a/Mage.Sets/src/mage/cards/m/MasterSplicer.java +++ b/Mage.Sets/src/mage/cards/m/MasterSplicer.java @@ -22,7 +22,7 @@ import java.util.UUID; */ public final class MasterSplicer extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.GOLEM, "Golem creatures"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.GOLEM, "Golems"); public MasterSplicer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); From be7dea2d1674aeb9ed45796dc116ebaca286da46 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 11 Dec 2019 04:44:25 +0400 Subject: [PATCH 07/10] * UI: fixed that split cards doesn't marks as playable; --- Mage/src/main/java/mage/players/PlayerImpl.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 77aa858ddc6..3b7bfae4942 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -22,10 +22,7 @@ import mage.abilities.keyword.*; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.ManaOptions; import mage.actions.MageDrawAction; -import mage.cards.Card; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.cards.SplitCard; +import mage.cards.*; import mage.cards.decks.Deck; import mage.choices.ChoiceImpl; import mage.constants.*; @@ -3414,6 +3411,13 @@ public abstract class PlayerImpl implements Player, Serializable { for (Ability ability : playableAbilities) { if (ability.getSourceId() != null) { playableObjects.add(ability.getSourceId()); + + // main card must be marked playable in GUI + MageObject object = game.getObject(ability.getSourceId()); + if (object instanceof SplitCardHalf) { + UUID splitCardId = ((Card) object).getMainCard().getId(); + playableObjects.add(splitCardId); + } } } return playableObjects; From 23324f21693d2a951dc98bb55cc3591c3a235e68 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Dec 2019 19:39:51 -0500 Subject: [PATCH 08/10] Added Theros: Beyond Death --- .../src/mage/sets/TherosBeyondDeath.java | 35 +++++++++++++++++++ Utils/known-sets.txt | 1 + Utils/mtg-cards-data.txt | 8 +++++ Utils/mtg-sets-data.txt | 1 + 4 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/TherosBeyondDeath.java diff --git a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java new file mode 100644 index 00000000000..02c0e974180 --- /dev/null +++ b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java @@ -0,0 +1,35 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class TherosBeyondDeath extends ExpansionSet { + + private static final TherosBeyondDeath instance = new TherosBeyondDeath(); + + public static TherosBeyondDeath getInstance() { + return instance; + } + + private TherosBeyondDeath() { + super("Theros: Beyond Death", "THB", ExpansionSet.buildDate(2020, 1, 24), SetType.EXPANSION); + this.blockName = "Theros: Beyond Death"; + this.hasBoosters = true; + this.numBoosterLands = 1; + this.numBoosterCommon = 10; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + this.maxCardNumberInBooster = 254; + + cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); + } +} diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index 638e5cb57ad..8e5ff711d0e 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -188,6 +188,7 @@ Tempest Remastered|TempestRemastered| Tenth Edition|TenthEdition| The Dark|TheDark| Theros|Theros| +Theros: Beyond Death|TherosBeyondDeath| Throne of Eldraine|ThroneOfEldraine| Throne of Eldraine Collector's Edition|ThroneOfEldraineCollectorsEdition| Time Spiral|TimeSpiral| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index d56646a2141..7307e64daa7 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -36434,3 +36434,11 @@ Sphinx of Enlightenment|Game Night 2019|2|M|{4}{U}{U}|Creature - Sphinx|5|5|Flyi Calculating Lich|Game Night 2019|3|M|{4}{B}{B}|Creature - Zombie Wizard|5|5|Menace$Whenever a creature attacks one of your opponents, that player loses 1 life.| Fiendish Duo|Game Night 2019|4|M|{4}{R}{R}|Creature - Devil|5|5|First strike$If a source would deal damage to an opponent, it deals double that damage that player instead.| Earthshaker Giant|Game Night 2019|5|M|{4}{G}{G}|Creature - Giant Druid|6|6|Trample$When Earthshaker Giant enters the battlefield, other creatures you control get +3/+3 and gain trample until end of turn.| +Elspeth, Sun's Nemesis|Theros: Beyond Death|14|M|{2}{W}{W}|Legendary Planeswalker - Elspeth|5|−1: Up to two target creatures you control each get +2/+1 until end of turn.$−2: Create two 1/1 white Human Soldier creature tokens.$−3: You gain 5 life.$Escape—{4}{W}{W}, Exile four other cards from your graveyard.| +Ashiok, Nightmare Muse|Theros: Beyond Death|208|M|{3}{U}{B}|Legendary Planeswalker - Ashiok|5|+1: Create a 2/3 blue and black Nightmare creature token with "Whenever this creature attacks or blocks, each opponent exiles the top two cards of their library."$−3: Return target nonland permanent to its owner's hand, then that player exiles a card from their hand.$−7: You may cast up to three face-up cards your opponents own from exile without paying their mana costs.| +Plains|Theros: Beyond Death|250|C||Basic Land - Plains|||({T}: Add {W}.)| +Island|Theros: Beyond Death|251|C||Basic Land - Island|||({T}: Add {U}.)| +Swamp|Theros: Beyond Death|252|C||Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Theros: Beyond Death|253|C||Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Theros: Beyond Death|254|C||Basic Land - Forest|||({T}: Add {G}.)| +Athreos, Shroud-Veiled|Theros: Beyond Death|269|M|{4}{W}{B}|Legendary Enchantment Creature - God|4|7|Indestructible$As long as your devotion to white and black is less than seven, Athreos isn't a creature.$At the beginning of your end step, put a coin counter on another target creature.$Whenever a creature with a coin counter on it dies or is put into exile, return that card to the battlefield under your control.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index 4b50c8d8d62..347ad206562 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -185,6 +185,7 @@ Scars of Mirrodin|SOM| Stronghold|STH| Super Series|SUS| Theros|THS| +Theros: Beyond Death|THB| Tempest|TMP| Throne of Eldraine|ELD| Throne of Eldraine Collector's Edition|CELD| From 3965061234ef370bde33048c2525a7d250923c09 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Dec 2019 20:08:07 -0500 Subject: [PATCH 09/10] Implemented Elspeth, Sun's Nemesis --- .../src/mage/cards/e/ElspethSunsNemesis.java | 56 +++++++++++++++++ .../src/mage/sets/TherosBeyondDeath.java | 1 + .../mage/abilities/keyword/EscapeAbility.java | 63 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/EscapeAbility.java diff --git a/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java new file mode 100644 index 00000000000..45c7b503ef5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java @@ -0,0 +1,56 @@ +package mage.cards.e; + +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.EscapeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.permanent.token.HumanSoldierToken; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ElspethSunsNemesis extends CardImpl { + + public ElspethSunsNemesis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELSPETH); + this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5)); + + // −1: Up to two target creatures you control each get +2/+1 until end of turn. + Ability ability = new LoyaltyAbility(new BoostTargetEffect(2, 1) + .setText("up to two target creatures you control each get +2/+1 until end of turn"), -1); + ability.addTarget(new TargetControlledCreaturePermanent(0, 2)); + this.addAbility(ability); + + // −2: Create two 1/1 white Human Soldier creature tokens. + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new HumanSoldierToken()), -2)); + + // −3: You gain 5 life. + this.addAbility(new LoyaltyAbility(new GainLifeEffect(5), -3)); + + // Escape—{4}{W}{W}, Exile four other cards from your graveyard. + this.addAbility(new EscapeAbility(this, "{4}{W}{W}", 4)); + } + + private ElspethSunsNemesis(final ElspethSunsNemesis card) { + super(card); + } + + @Override + public ElspethSunsNemesis copy() { + return new ElspethSunsNemesis(this); + } +} diff --git a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java index 02c0e974180..c697572517c 100644 --- a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java +++ b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java @@ -26,6 +26,7 @@ public final class TherosBeyondDeath extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 254; + cards.add(new SetCardInfo("Elspeth, Sun's Nemesis", 14, Rarity.MYTHIC, mage.cards.e.ElspethSunsNemesis.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/keyword/EscapeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EscapeAbility.java new file mode 100644 index 00000000000..78961979a87 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/EscapeAbility.java @@ -0,0 +1,63 @@ +package mage.abilities.keyword; + +import mage.abilities.SpellAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.cards.Card; +import mage.constants.SpellAbilityType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class EscapeAbility extends SpellAbility { + + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(AnotherPredicate.instance); + } + + private final String manaCost; + private final int exileCount; + + public EscapeAbility(Card card, String manaCost, int exileCount) { + super(new ManaCostsImpl(manaCost), card.getName() + " with escape"); + this.newId(); + this.zone = Zone.GRAVEYARD; + this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; + this.manaCost = manaCost; + this.exileCount = exileCount; + + Cost cost = new ExileFromGraveCost(new TargetCardInYourGraveyard(exileCount, filter)); + cost.setText(""); + this.addCost(cost); + } + + private EscapeAbility(final EscapeAbility ability) { + super(ability); + this.manaCost = ability.manaCost; + this.exileCount = ability.exileCount; + } + + @Override + public EscapeAbility copy() { + return new EscapeAbility(this); + } + + @Override + public String getRule(boolean all) { + return getRule(); + } + + @Override + public String getRule() { + return "Escape — " + this.manaCost + ", Exile " + CardUtil.numberToText(this.exileCount) + + " other cards from your graveyard. (You may cast this card from your graveyard for its escape cost.)"; + } +} From a2c142df419ceea276e49c167b7cae4242cb0118 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Dec 2019 20:50:23 -0500 Subject: [PATCH 10/10] fixed the amount of tokens made by Elspeth, Sun's Nemesis --- Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java index 45c7b503ef5..22c8b5ef11b 100644 --- a/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java +++ b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java @@ -36,7 +36,7 @@ public final class ElspethSunsNemesis extends CardImpl { this.addAbility(ability); // −2: Create two 1/1 white Human Soldier creature tokens. - this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new HumanSoldierToken()), -2)); + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new HumanSoldierToken(), 2), -2)); // −3: You gain 5 life. this.addAbility(new LoyaltyAbility(new GainLifeEffect(5), -3));