From 44ad71f2e0d226168085c866f9b3ec90b3e2a967 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sat, 25 May 2024 14:17:06 +0200 Subject: [PATCH] implement [MH3] Argent Dais --- Mage.Sets/src/mage/cards/a/ArgentDais.java | 130 ++++++++++++++++++ .../src/mage/cards/d/DuelistsHeritage.java | 7 +- .../src/mage/cards/l/LightmineField.java | 15 +- .../src/mage/cards/r/RoarOfResistance.java | 6 +- Mage.Sets/src/mage/sets/ModernHorizons3.java | 1 + .../test/cards/single/mh3/ArgentDaisTest.java | 108 +++++++++++++++ 6 files changed, 253 insertions(+), 14 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/ArgentDais.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/ArgentDaisTest.java diff --git a/Mage.Sets/src/mage/cards/a/ArgentDais.java b/Mage.Sets/src/mage/cards/a/ArgentDais.java new file mode 100644 index 00000000000..2822c82e27f --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArgentDais.java @@ -0,0 +1,130 @@ +package mage.cards.a; + +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetNonlandPermanent; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class ArgentDais extends CardImpl { + + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("another nonland permanent"); + + static { + filter.add(AnotherPredicate.instance); + } + + public ArgentDais(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}"); + + // Argent Dais enters the battlefield with two oil counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.OIL.createInstance(2)), + "with two oil counters on it" + )); + + // Whenever two or more creatures attack, put an oil counter on Argent Dais. + this.addAbility(new ArgentDaisTriggeredAbility()); + + // {2}, {T}, Remove two oil counters from Argent Dais: Exile another target nonland permanent. Its controller draws two cards. + Ability ability = new SimpleActivatedAbility( + new ExileTargetEffect(), + new GenericManaCost(2) + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new RemoveCountersSourceCost(CounterType.OIL.createInstance(2))); + ability.addTarget(new TargetNonlandPermanent(filter)); + ability.addEffect(new ArgentDaisTargetEffect()); + this.addAbility(ability); + } + + private ArgentDais(final ArgentDais card) { + super(card); + } + + @Override + public ArgentDais copy() { + return new ArgentDais(this); + } +} + +class ArgentDaisTriggeredAbility extends TriggeredAbilityImpl { + + ArgentDaisTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.OIL.createInstance())); + setTriggerPhrase("Whenever two or more creatures attack, "); + } + + private ArgentDaisTriggeredAbility(final ArgentDaisTriggeredAbility ability) { + super(ability); + } + + @Override + public ArgentDaisTriggeredAbility copy() { + return new ArgentDaisTriggeredAbility(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.getCombat().getAttackers().size() >= 2; + } +} + +class ArgentDaisTargetEffect extends OneShotEffect { + + ArgentDaisTargetEffect() { + super(Outcome.DrawCard); + this.staticText = "its controller draws two cards"; + } + + private ArgentDaisTargetEffect(final ArgentDaisTargetEffect effect) { + super(effect); + } + + @Override + public ArgentDaisTargetEffect copy() { + return new ArgentDaisTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); + if (permanent == null) { + return false; + } + Player controllerOfTarget = game.getPlayer(permanent.getControllerId()); + if (controllerOfTarget == null) { + return false; + } + controllerOfTarget.drawCards(2, source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuelistsHeritage.java b/Mage.Sets/src/mage/cards/d/DuelistsHeritage.java index 0b1ed08348c..b8ae9f11e06 100644 --- a/Mage.Sets/src/mage/cards/d/DuelistsHeritage.java +++ b/Mage.Sets/src/mage/cards/d/DuelistsHeritage.java @@ -1,6 +1,5 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -15,11 +14,11 @@ import mage.constants.Zone; import mage.filter.common.FilterAttackingCreature; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author fireshoes */ public final class DuelistsHeritage extends CardImpl { @@ -50,7 +49,7 @@ public final class DuelistsHeritage extends CardImpl { class DuelistsHeritageTriggeredAbility extends TriggeredAbilityImpl { - public DuelistsHeritageTriggeredAbility(Zone zone, Effect effect) { + DuelistsHeritageTriggeredAbility(Zone zone, Effect effect) { super(zone, effect, true); } diff --git a/Mage.Sets/src/mage/cards/l/LightmineField.java b/Mage.Sets/src/mage/cards/l/LightmineField.java index d14eefbe962..1d87da942f2 100644 --- a/Mage.Sets/src/mage/cards/l/LightmineField.java +++ b/Mage.Sets/src/mage/cards/l/LightmineField.java @@ -1,9 +1,5 @@ package mage.cards.l; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -16,11 +12,14 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class LightmineField extends CardImpl { @@ -44,7 +43,7 @@ public final class LightmineField extends CardImpl { class LightmineFieldTriggeredAbility extends TriggeredAbilityImpl { - public LightmineFieldTriggeredAbility() { + LightmineFieldTriggeredAbility() { super(Zone.BATTLEFIELD, new LightmineFieldEffect()); setTriggerPhrase("Whenever one or more creatures attack, "); } @@ -100,7 +99,7 @@ class LightmineFieldEffect extends OneShotEffect { int damage = game.getCombat().getAttackers().size(); Set attackSet = (Set) getValue("Lightmine Field"); if (damage > 0) { - for (Iterator it = attackSet.iterator(); it.hasNext();) { + for (Iterator it = attackSet.iterator(); it.hasNext(); ) { MageObjectReference attacker = it.next(); Permanent creature = attacker.getPermanent(game); if (creature != null) { diff --git a/Mage.Sets/src/mage/cards/r/RoarOfResistance.java b/Mage.Sets/src/mage/cards/r/RoarOfResistance.java index af39b9cf3a0..786e0fb14dc 100644 --- a/Mage.Sets/src/mage/cards/r/RoarOfResistance.java +++ b/Mage.Sets/src/mage/cards/r/RoarOfResistance.java @@ -72,13 +72,15 @@ enum RoarOfResistancePredicate implements ObjectSourcePlayerPredicate && attackedPlaneswalker.isPlaneswalker(game) && opponents.contains(attackedPlaneswalker.getControllerId())) { return true; - } else return opponents.contains(defenderId); + } else { + return opponents.contains(defenderId); + } } } class RoarOfResistanceTriggeredAbility extends TriggeredAbilityImpl { - public RoarOfResistanceTriggeredAbility(Zone zone, Effect effect) { + RoarOfResistanceTriggeredAbility(Zone zone, Effect effect) { super(zone, effect, false); } diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3.java b/Mage.Sets/src/mage/sets/ModernHorizons3.java index 1948e60f9f5..27f55a7bae5 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons3.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons3.java @@ -23,6 +23,7 @@ public final class ModernHorizons3 extends ExpansionSet { cards.add(new SetCardInfo("Ajani, Nacatl Avenger", 237, Rarity.MYTHIC, mage.cards.a.AjaniNacatlAvenger.class)); cards.add(new SetCardInfo("Ajani, Nacatl Pariah", 237, Rarity.MYTHIC, mage.cards.a.AjaniNacatlPariah.class)); + cards.add(new SetCardInfo("Argent Dais", 20, Rarity.RARE, mage.cards.a.ArgentDais.class)); cards.add(new SetCardInfo("Barbarian Ring", 299, Rarity.UNCOMMON, mage.cards.b.BarbarianRing.class)); cards.add(new SetCardInfo("Basking Broodscale", 145, Rarity.COMMON, mage.cards.b.BaskingBroodscale.class)); cards.add(new SetCardInfo("Bloodsoaked Insight", 252, Rarity.UNCOMMON, mage.cards.b.BloodsoakedInsight.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/ArgentDaisTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/ArgentDaisTest.java new file mode 100644 index 00000000000..93ee972fb58 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/ArgentDaisTest.java @@ -0,0 +1,108 @@ +package org.mage.test.cards.single.mh3; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class ArgentDaisTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.a.ArgentDais Argent Dais} {1}{W} + * Artifact + * Argent Dais enters the battlefield with two oil counters on it. + * Whenever two or more creatures attack, put an oil counter on Argent Dais. + * {2}, {T}, Remove two oil counters from Argent Dais: Exile another target nonland permanent. Its controller draws two cards. + */ + private static final String dais = "Argent Dais"; + + @Test + public void test_Attack_One_No_Trigger() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, dais); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + + attack(1, playerA, "Grizzly Bears", playerB); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 20 - 2); + assertCounterCount(playerA, dais, CounterType.OIL, 2); + } + + @Test + public void test_Attack_Two_Trigger() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, dais); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Memnite"); + + attack(1, playerA, "Grizzly Bears", playerB); + attack(1, playerA, "Memnite", playerB); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 20 - 2 - 1); + assertCounterCount(playerA, dais, CounterType.OIL, 2 + 1); + } + + @Test + public void test_Attack_Two_OtherPlayer_Trigger() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerB, dais); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Memnite"); + + attack(1, playerA, "Grizzly Bears", playerB); + attack(1, playerA, "Memnite", playerB); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 20 - 2 - 1); + assertCounterCount(playerB, dais, CounterType.OIL, 2 + 1); + } + + @Test + public void test_Activate_On_Own_Creature() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, dais); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}", "Grizzly Bears"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, "Grizzly Bears", 1); + assertHandCount(playerA, 2); + } + + @Test + public void test_Activate_On_Opponent_Creature() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, dais); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}", "Grizzly Bears"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerB, "Grizzly Bears", 1); + assertHandCount(playerB, 2); + } +}