From a979bbfdaee02f87d6aaa025e6e093208153d944 Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Sat, 24 Aug 2019 14:24:50 +0200 Subject: [PATCH 01/12] fix Jeskai Infiltrator --- Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java b/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java index 668374e0b0..adaf3d748a 100644 --- a/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java +++ b/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java @@ -95,8 +95,8 @@ class JeskaiInfiltratorEffect extends OneShotEffect { Ability newSource = source.copy(); newSource.setWorksFaceDown(true); - while (!exileZone.isEmpty()) { - Card card = exileZone.getRandom(game); + //the Set will mimic the Shuffling + exileZone.getCards(game).forEach(card -> { ManaCosts manaCosts = null; if (card.isCreature()) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -106,7 +106,7 @@ class JeskaiInfiltratorEffect extends OneShotEffect { } MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - } + }); controller.moveCards(exileZone.getCards(game), Zone.BATTLEFIELD, source, game, false, true, false, null); return true; } From c3b3553e294643aaff31a5f558c4d2dd3fdf8141 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 12:25:28 -0400 Subject: [PATCH 02/12] updated Modern ban list --- .../Mage.Deck.Constructed/src/mage/deck/Modern.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Modern.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Modern.java index 9443c893b3..ad712c16cf 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Modern.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Modern.java @@ -33,11 +33,13 @@ public class Modern extends Constructed { banned.add("Dig Through Time"); banned.add("Dread Return"); banned.add("Eye of Ugin"); + banned.add("Faithless Looting"); banned.add("Gitaxian Probe"); banned.add("Glimpse of Nature"); banned.add("Golgari Grave-Troll"); banned.add("Great Furnace"); banned.add("Green Sun's Zenith"); + banned.add("Hogaak, Arisen Necropolis"); banned.add("Hypergenesis"); banned.add("Krark-Clan Ironworks"); banned.add("Mental Misstep"); @@ -49,7 +51,6 @@ public class Modern extends Constructed { banned.add("Second Sunrise"); banned.add("Seething Song"); banned.add("Sensei's Divining Top"); - banned.add("Stoneforge Mystic"); banned.add("Skullclamp"); banned.add("Splinter Twin"); banned.add("Summer Bloom"); From 14081a7ac532116c22bba1e59e2e3d11a854be97 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 12:26:03 -0400 Subject: [PATCH 03/12] updated Standard ban list --- .../Mage.Deck.Constructed/src/mage/deck/Standard.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java index dd54b019f3..6abe881da1 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java @@ -16,8 +16,6 @@ public class Standard extends Constructed { super("Constructed - Standard"); setCodes.addAll(makeLegalSets()); - - banned.add("Rampaging Ferocidon"); // since 2018-01-15 } private static boolean isFallSet(ExpansionSet set) { From 1f1eb08609aea5dbc4e8cefda25e45247e0f46d2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 12:29:19 -0400 Subject: [PATCH 04/12] updated Vintage ban and restricted list --- .../Mage.Deck.Constructed/src/mage/deck/Vintage.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java index 481479cbc2..1a4035502b 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java @@ -51,11 +51,12 @@ public class Vintage extends Constructed { restricted.add("Demonic Consultation"); restricted.add("Demonic Tutor"); restricted.add("Dig Through Time"); - restricted.add("Fastbond"); restricted.add("Flash"); restricted.add("Gitaxian Probe"); + restricted.add("Golgari Grave-Troll"); restricted.add("Gush"); restricted.add("Imperial Seal"); + restricted.add("Karn, the Great Creator"); restricted.add("Library of Alexandria"); restricted.add("Lion's Eye Diamond"); restricted.add("Lodestone Golem"); @@ -63,6 +64,7 @@ public class Vintage extends Constructed { restricted.add("Mana Crypt"); restricted.add("Mana Vault"); restricted.add("Memory Jar"); + restricted.add("Mental Misstep"); restricted.add("Merchant Scroll"); restricted.add("Mind's Desire"); restricted.add("Monastery Mentory"); @@ -71,6 +73,7 @@ public class Vintage extends Constructed { restricted.add("Mox Pearl"); restricted.add("Mox Ruby"); restricted.add("Mox Sapphire"); + restricted.add("Mystic Forge"); restricted.add("Mystical Tutor"); restricted.add("Necropotence"); restricted.add("Ponder"); From 217e4b14e02183a821ef51998b6b5ae07175ab56 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 12:49:08 -0400 Subject: [PATCH 05/12] Implemented Wellspring --- Mage.Sets/src/mage/cards/w/Wellspring.java | 90 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Mirage.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/Wellspring.java diff --git a/Mage.Sets/src/mage/cards/w/Wellspring.java b/Mage.Sets/src/mage/cards/w/Wellspring.java new file mode 100644 index 0000000000..56173302cc --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/Wellspring.java @@ -0,0 +1,90 @@ +package mage.cards.w; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.UntapEnchantedEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetLandPermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Wellspring extends CardImpl { + + public Wellspring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant land + TargetPermanent auraTarget = new TargetLandPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Wellspring enters the battlefield, gain control of enchanted land until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new WellspringEffect("gain control of enchanted land until end of turn") + )); + + // At the beginning of your upkeep, untap enchanted land. You gain control of that land until end of turn. + ability = new BeginningOfUpkeepTriggeredAbility( + new UntapEnchantedEffect().setText("untap enchanted land."), TargetController.YOU, false + ); + ability.addEffect(new WellspringEffect("You gain control of that land until end of turn")); + this.addAbility(ability); + } + + private Wellspring(final Wellspring card) { + super(card); + } + + @Override + public Wellspring copy() { + return new Wellspring(this); + } +} + +class WellspringEffect extends OneShotEffect { + + WellspringEffect(String text) { + super(Outcome.Benefit); + staticText = text; + } + + private WellspringEffect(final WellspringEffect effect) { + super(effect); + } + + @Override + public WellspringEffect copy() { + return new WellspringEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (permanent == null) { + return false; + } + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent.getAttachedTo(), game)); + game.addEffect(effect, source); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index 6e87d40a7c..d474bd9f6b 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -329,6 +329,7 @@ public final class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Ward of Lights", 47, Rarity.COMMON, mage.cards.w.WardOfLights.class)); cards.add(new SetCardInfo("Warping Wurm", 287, Rarity.RARE, mage.cards.w.WarpingWurm.class)); cards.add(new SetCardInfo("Wave Elemental", 102, Rarity.UNCOMMON, mage.cards.w.WaveElemental.class)); + cards.add(new SetCardInfo("Wellspring", 348, Rarity.RARE, mage.cards.w.Wellspring.class)); cards.add(new SetCardInfo("Wild Elephant", 254, Rarity.COMMON, mage.cards.w.WildElephant.class)); cards.add(new SetCardInfo("Wildfire Emissary", 203, Rarity.UNCOMMON, mage.cards.w.WildfireEmissary.class)); cards.add(new SetCardInfo("Windreaper Falcon", 289, Rarity.UNCOMMON, mage.cards.w.WindreaperFalcon.class)); From 15546ab93a7499420e03c9a64cd9da1b11422916 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 12:57:30 -0400 Subject: [PATCH 06/12] Implemented Empowered Autogenerator --- .../mage/cards/e/EmpoweredAutogenerator.java | 129 ++++++++++++++++++ .../src/mage/sets/Commander2019Edition.java | 1 + 2 files changed, 130 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java diff --git a/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java b/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java new file mode 100644 index 0000000000..1b78cf12c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java @@ -0,0 +1,129 @@ +package mage.cards.e; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ManaEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EmpoweredAutogenerator extends CardImpl { + + public EmpoweredAutogenerator(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // Empowered Autogenerator enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {T}: Put a charge counter on Empowered Autogenerator. Add X mana of any one color, where X is the number of charge counters on Empowered Autogenerator. + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AstralCornucopiaManaEffect(), new TapSourceCost())); + } + + private EmpoweredAutogenerator(final EmpoweredAutogenerator card) { + super(card); + } + + @Override + public EmpoweredAutogenerator copy() { + return new EmpoweredAutogenerator(this); + } +} + +class AstralCornucopiaManaEffect extends ManaEffect { + + private final Mana computedMana; + + AstralCornucopiaManaEffect() { + super(); + computedMana = new Mana(); + this.staticText = "Put a charge counter on {this}. Add X mana of any one color, " + + "where X is the number of charge counters on {this}"; + } + + private AstralCornucopiaManaEffect(final AstralCornucopiaManaEffect effect) { + super(effect); + this.computedMana = effect.computedMana.copy(); + } + + @Override + public AstralCornucopiaManaEffect copy() { + return new AstralCornucopiaManaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + checkToFirePossibleEvents(getMana(game, source), game, source); + controller.getManaPool().addMana(getMana(game, source), game, source); + return true; + + } + + @Override + public Mana produceMana(boolean netMana, Game game, Ability source) { + Mana mana = new Mana(); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent == null) { + return mana; + } + sourcePermanent.addCounters(CounterType.CHARGE.createInstance(), source, game); + game.applyEffects(); + int counters = sourcePermanent.getCounters(game).getCount(CounterType.CHARGE); + if (counters <= 0) { + return mana; + } + if (netMana) { + return new Mana(0, 0, 0, 0, 0, 0, counters, 0); + } + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return mana; + } + ChoiceColor choice = new ChoiceColor(); + choice.setMessage("Choose a color to add mana of that color"); + if (!controller.choose(outcome, choice, game)) { + return mana; + } + if (choice.getChoice() == null) { + return mana; + } + String color = choice.getChoice(); + switch (color) { + case "Red": + mana.setRed(counters); + break; + case "Blue": + mana.setBlue(counters); + break; + case "White": + mana.setWhite(counters); + break; + case "Black": + mana.setBlack(counters); + break; + case "Green": + mana.setGreen(counters); + break; + } + + return mana; + } + +} diff --git a/Mage.Sets/src/mage/sets/Commander2019Edition.java b/Mage.Sets/src/mage/sets/Commander2019Edition.java index 3b6c32b3b6..1919516949 100644 --- a/Mage.Sets/src/mage/sets/Commander2019Edition.java +++ b/Mage.Sets/src/mage/sets/Commander2019Edition.java @@ -90,6 +90,7 @@ public final class Commander2019Edition extends ExpansionSet { cards.add(new SetCardInfo("Elemental Bond", 163, Rarity.UNCOMMON, mage.cards.e.ElementalBond.class)); cards.add(new SetCardInfo("Elsha of the Infinite", 40, Rarity.MYTHIC, mage.cards.e.ElshaOfTheInfinite.class)); cards.add(new SetCardInfo("Emmara Tandris", 191, Rarity.RARE, mage.cards.e.EmmaraTandris.class)); + cards.add(new SetCardInfo("Empowered Autogenerator", 54, Rarity.RARE, mage.cards.e.EmpoweredAutogenerator.class)); cards.add(new SetCardInfo("Evolving Wilds", 241, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); cards.add(new SetCardInfo("Exotic Orchard", 242, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); cards.add(new SetCardInfo("Explore", 164, Rarity.COMMON, mage.cards.e.Explore.class)); From a206b5feb172611c777656afab4587db5df28f1d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 13:00:21 -0400 Subject: [PATCH 07/12] fixed Wellspring collector number --- Mage.Sets/src/mage/sets/Mirage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index d474bd9f6b..5b885dbccd 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -329,7 +329,7 @@ public final class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Ward of Lights", 47, Rarity.COMMON, mage.cards.w.WardOfLights.class)); cards.add(new SetCardInfo("Warping Wurm", 287, Rarity.RARE, mage.cards.w.WarpingWurm.class)); cards.add(new SetCardInfo("Wave Elemental", 102, Rarity.UNCOMMON, mage.cards.w.WaveElemental.class)); - cards.add(new SetCardInfo("Wellspring", 348, Rarity.RARE, mage.cards.w.Wellspring.class)); + cards.add(new SetCardInfo("Wellspring", 288, Rarity.RARE, mage.cards.w.Wellspring.class)); cards.add(new SetCardInfo("Wild Elephant", 254, Rarity.COMMON, mage.cards.w.WildElephant.class)); cards.add(new SetCardInfo("Wildfire Emissary", 203, Rarity.UNCOMMON, mage.cards.w.WildfireEmissary.class)); cards.add(new SetCardInfo("Windreaper Falcon", 289, Rarity.UNCOMMON, mage.cards.w.WindreaperFalcon.class)); From 8941dd852a003a2a0e6795482254b676ca9fd57b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 13:27:07 -0400 Subject: [PATCH 08/12] Implemented Wildfire Devils --- .../src/mage/cards/w/WildfireDevils.java | 113 ++++++++++++++++++ .../src/mage/sets/Commander2019Edition.java | 1 + 2 files changed, 114 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WildfireDevils.java diff --git a/Mage.Sets/src/mage/cards/w/WildfireDevils.java b/Mage.Sets/src/mage/cards/w/WildfireDevils.java new file mode 100644 index 0000000000..b9165df243 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildfireDevils.java @@ -0,0 +1,113 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.meta.OrTriggeredAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInGraveyard; +import org.apache.log4j.Logger; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WildfireDevils extends CardImpl { + + public WildfireDevils(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.DEVIL); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // When Wildfire Devils enters the battlefield and at the beginning of your upkeep, choose a player at random. That player exiles an instant or sorcery card from their graveyard. Copy that card. You may cast the copy without paying its mana cost. + this.addAbility(new OrTriggeredAbility( + Zone.BATTLEFIELD, new WildfireDevilsEffect(), false, + "When {this} enters the battlefield and at the beginning of your upkeep, ", + new EntersBattlefieldTriggeredAbility(null, false), + new BeginningOfUpkeepTriggeredAbility(null, TargetController.YOU, false) + )); + } + + private WildfireDevils(final WildfireDevils card) { + super(card); + } + + @Override + public WildfireDevils copy() { + return new WildfireDevils(this); + } +} + +class WildfireDevilsEffect extends OneShotEffect { + + WildfireDevilsEffect() { + super(Outcome.Benefit); + staticText = "choose a player at random. That player exiles an instant or sorcery card from their graveyard. " + + "Copy that card. You may cast the copy without paying its mana cost."; + } + + private WildfireDevilsEffect(final WildfireDevilsEffect effect) { + super(effect); + } + + @Override + public WildfireDevilsEffect copy() { + return new WildfireDevilsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + TargetPlayer targetPlayer = new TargetPlayer(); + targetPlayer.setRandom(true); + targetPlayer.setNotTarget(true); + if (!controller.choose(outcome, targetPlayer, source.getSourceId(), game)) { + return false; + } + Player player = game.getPlayer(targetPlayer.getFirstTarget()); + if (player == null || player.getGraveyard().getCards(game).stream().noneMatch(Card::isInstantOrSorcery)) { + return false; + } + TargetCard targetCard = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY); + targetCard.setNotTarget(true); + if (!player.choose(outcome, player.getGraveyard(), targetCard, game)) { + return false; + } + Card card = game.getCard(targetCard.getFirstTarget()); + player.moveCards(card, Zone.EXILED, source, game); + if (game.getState().getZone(card.getId()) != Zone.EXILED) { + return false; + } + Card copiedCard = game.copyCard(card, source, controller.getId()); + if (copiedCard == null) { + return false; + } + game.getExile().add(source.getSourceId(), "", card); + game.setZone(copiedCard.getId(), Zone.EXILED); + if (!controller.chooseUse(outcome, "Cast the exiled card?", source, game)) { + return true; + } + if (copiedCard.getSpellAbility() == null) { + Logger.getLogger(WildfireDevilsEffect.class).error("Wildfire Devils: spell ability == null " + copiedCard.getName()); + return true; + } + return controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Commander2019Edition.java b/Mage.Sets/src/mage/sets/Commander2019Edition.java index 1919516949..6a8831f344 100644 --- a/Mage.Sets/src/mage/sets/Commander2019Edition.java +++ b/Mage.Sets/src/mage/sets/Commander2019Edition.java @@ -296,6 +296,7 @@ public final class Commander2019Edition extends ExpansionSet { cards.add(new SetCardInfo("Vraska the Unseen", 207, Rarity.MYTHIC, mage.cards.v.VraskaTheUnseen.class)); cards.add(new SetCardInfo("Warstorm Surge", 155, Rarity.RARE, mage.cards.w.WarstormSurge.class)); cards.add(new SetCardInfo("Wayfaring Temple", 208, Rarity.RARE, mage.cards.w.WayfaringTemple.class)); + cards.add(new SetCardInfo("Wildfire Devils", 30, Rarity.RARE, mage.cards.w.WildfireDevils.class)); cards.add(new SetCardInfo("Willbender", 102, Rarity.UNCOMMON, mage.cards.w.Willbender.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 285, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wingmate Roc", 78, Rarity.MYTHIC, mage.cards.w.WingmateRoc.class)); From 96edac2385c99db43789764ebfaf05445f77f915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20M=C3=A1r=20=C3=93ttarsson?= Date: Mon, 26 Aug 2019 19:15:56 +0000 Subject: [PATCH 09/12] Fixed sac eff wording --- Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java index 0edaaf5444..a124319640 100644 --- a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java +++ b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java @@ -65,7 +65,7 @@ class RangerCaptainOfEosEffect extends ContinuousRuleModifyingEffectImpl { RangerCaptainOfEosEffect() { super(Duration.EndOfTurn, Outcome.Benefit); - staticText = "Your opponents can't noncreature cast spells this turn."; + staticText = "Your opponents can't cast noncreature spells this turn."; } private RangerCaptainOfEosEffect(final RangerCaptainOfEosEffect effect) { From fb6a7886b01edebf75c600ca267b5cb0ffef4e92 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 26 Aug 2019 18:30:13 -0400 Subject: [PATCH 10/12] Implemented Tahngarth, First Mate --- .../src/mage/cards/t/TahngarthFirstMate.java | 157 ++++++++++++++++++ .../src/mage/sets/Commander2019Edition.java | 1 + 2 files changed, 158 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java diff --git a/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java b/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java new file mode 100644 index 0000000000..693bf559f0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java @@ -0,0 +1,157 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterPlayerOrPlaneswalker; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetPlayerOrPlaneswalker; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TahngarthFirstMate extends CardImpl { + + public TahngarthFirstMate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.MINOTAUR); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Tahngarth, First Mate can't be blocked by more than one creature. + this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneSourceEffect())); + + // Whenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker. + this.addAbility(new TahngarthFirstMateTriggeredAbility()); + } + + private TahngarthFirstMate(final TahngarthFirstMate card) { + super(card); + } + + @Override + public TahngarthFirstMate copy() { + return new TahngarthFirstMate(this); + } +} + +class TahngarthFirstMateTriggeredAbility extends TriggeredAbilityImpl { + + TahngarthFirstMateTriggeredAbility() { + super(Zone.BATTLEFIELD, new TahngarthFirstMateEffect(), true); + } + + private TahngarthFirstMateTriggeredAbility(final TahngarthFirstMateTriggeredAbility ability) { + super(ability); + } + + @Override + public TahngarthFirstMateTriggeredAbility copy() { + return new TahngarthFirstMateTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.getOpponents(getControllerId()).contains(game.getActivePlayerId()) + && !game.getCombat().getAttackers().isEmpty(); + } + + @Override + public boolean checkInterveningIfClause(Game game) { + Permanent permanent = game.getPermanent(getSourceId()); + return permanent != null && permanent.isTapped(); + } + + @Override + public String getRule() { + return "Whenever an opponent attacks with one or more creatures, " + + "if {this} is tapped, you may have that opponent gain control of {this} until end of combat. " + + "If you do, choose a player or planeswalker that opponent is attacking. " + + "{this} is attacking that player or planeswalker."; + } +} + +class TahngarthFirstMateEffect extends OneShotEffect { + + private static final FilterPlayerOrPlaneswalker filter + = new FilterPlayerOrPlaneswalker("player or planeswalker active player is attacking"); + + static { + filter.getPlayerFilter().add(TahngarthFirstMatePlayerPredicate.instance); + filter.getPermanentFilter().add(TahngarthFirstMatePermanentPredicate.instance); + } + + TahngarthFirstMateEffect() { + super(Outcome.Benefit); + } + + private TahngarthFirstMateEffect(final TahngarthFirstMateEffect effect) { + super(effect); + } + + @Override + public TahngarthFirstMateEffect copy() { + return new TahngarthFirstMateEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(game.getActivePlayerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (controller == null || player == null || permanent == null) { + return false; + } + TargetPlayerOrPlaneswalker target = new TargetPlayerOrPlaneswalker(filter); + target.setNotTarget(true); + if (!controller.choose(outcome, target, source.getSourceId(), game)) { + return false; + } + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfCombat, player.getId()); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + game.applyEffects(); + return game.getCombat().addAttackerToCombat(permanent.getId(), target.getFirstTarget(), game); + } +} + +enum TahngarthFirstMatePlayerPredicate implements Predicate { + instance; + + @Override + public boolean apply(Player input, Game game) { + return game.getCombat().getDefenders().contains(input.getId()); + } +} + +enum TahngarthFirstMatePermanentPredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return game.getCombat().getDefenders().contains(input.getId()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Commander2019Edition.java b/Mage.Sets/src/mage/sets/Commander2019Edition.java index 6a8831f344..66739aecf9 100644 --- a/Mage.Sets/src/mage/sets/Commander2019Edition.java +++ b/Mage.Sets/src/mage/sets/Commander2019Edition.java @@ -266,6 +266,7 @@ public final class Commander2019Edition extends ExpansionSet { cards.add(new SetCardInfo("Sunken Hollow", 278, Rarity.RARE, mage.cards.s.SunkenHollow.class)); cards.add(new SetCardInfo("Swamp", 294, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swiftwater Cliffs", 279, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class)); + cards.add(new SetCardInfo("Tahngarth, First Mate", 50, Rarity.RARE, mage.cards.t.TahngarthFirstMate.class)); cards.add(new SetCardInfo("Talrand, Sky Summoner", 97, Rarity.RARE, mage.cards.t.TalrandSkySummoner.class)); cards.add(new SetCardInfo("Tectonic Hellion", 29, Rarity.RARE, mage.cards.t.TectonicHellion.class)); cards.add(new SetCardInfo("Temple of the False God", 280, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class)); From df459172de101cf06a4cd12e87f4b50d1bf5a7fc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 27 Aug 2019 17:38:24 -0400 Subject: [PATCH 11/12] fixed Hate Mirage not working --- Mage.Sets/src/mage/cards/h/HateMirage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/h/HateMirage.java b/Mage.Sets/src/mage/cards/h/HateMirage.java index 54c78fa231..15ca94ff06 100644 --- a/Mage.Sets/src/mage/cards/h/HateMirage.java +++ b/Mage.Sets/src/mage/cards/h/HateMirage.java @@ -74,7 +74,7 @@ class HateMirageEffect extends OneShotEffect { .flatMap(Collection::stream) .forEach(uuid -> { CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect( - source.getId(), null, true + source.getControllerId(), null, true ); effect.setTargetPointer(new FixedTarget(uuid, game)); effect.apply(game, source); From 70787df5eae06a0ff0baf0e5480d06dac733627d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 27 Aug 2019 17:40:10 -0400 Subject: [PATCH 12/12] fixed Leadership Vacuum not working --- Mage.Sets/src/mage/cards/l/LeadershipVacuum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java b/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java index 26f7231ecc..778a9d7282 100644 --- a/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java +++ b/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java @@ -67,7 +67,7 @@ class LeadershipVacuumEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(source.getFirstTarget()); if (player == null) { return false; }