From a4b49657796228cad30f70b066ab2e2ad32e3537 Mon Sep 17 00:00:00 2001 From: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com> Date: Wed, 2 Nov 2022 02:15:33 +0000 Subject: [PATCH 1/3] [BRO] Implement Raze to the Ground --- .../src/mage/cards/r/RazeToTheGround.java | 82 +++++++++++++++++++ Mage.Sets/src/mage/sets/TheBrothersWar.java | 1 + 2 files changed, 83 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RazeToTheGround.java diff --git a/Mage.Sets/src/mage/cards/r/RazeToTheGround.java b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java new file mode 100644 index 00000000000..f3f7f6473b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java @@ -0,0 +1,82 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetArtifactPermanent; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class RazeToTheGround extends CardImpl { + + public RazeToTheGround(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); + + // This spell can't be countered. + Effect effect = new CantBeCounteredSourceEffect(); + effect.setText("this spell can't be countered"); + Ability ability = new SimpleStaticAbility(Zone.STACK, effect); + ability.setRuleAtTheTop(true); + this.addAbility(ability); + + // Destroy target artifact. If its mana value was 1 or less, draw a card. + this.getSpellAbility().addEffect(new RazeToTheGroundEffect()); + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); + } + + private RazeToTheGround(final RazeToTheGround card) { + super(card); + } + + @Override + public RazeToTheGround copy() { + return new RazeToTheGround(this); + } +} + +class RazeToTheGroundEffect extends OneShotEffect { + + public RazeToTheGroundEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target artifact. If its mana value was 1 or less, draw a card."; + } + + private RazeToTheGroundEffect(final RazeToTheGroundEffect effect) { + super(effect); + } + + @Override + public RazeToTheGroundEffect copy() { + return new RazeToTheGroundEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + int manaValue = permanent.getManaValue(); + permanent.destroy(source, game); + if (manaValue <= 1) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.drawCards(1, source, game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/TheBrothersWar.java b/Mage.Sets/src/mage/sets/TheBrothersWar.java index dcd7dd2ea8d..a1a5091af8e 100644 --- a/Mage.Sets/src/mage/sets/TheBrothersWar.java +++ b/Mage.Sets/src/mage/sets/TheBrothersWar.java @@ -87,6 +87,7 @@ public final class TheBrothersWar extends ExpansionSet { cards.add(new SetCardInfo("Plains", 278, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Powerstone Fracture", 112, Rarity.COMMON, mage.cards.p.PowerstoneFracture.class)); cards.add(new SetCardInfo("Queen Kayla bin-Kroog", 218, Rarity.RARE, mage.cards.q.QueenKaylaBinKroog.class)); + cards.add(new SetCardInfo("Raze to the Ground", 149, Rarity.COMMON, mage.cards.r.RazeToTheGround.class)); cards.add(new SetCardInfo("Reconstructed Thopter", 242, Rarity.UNCOMMON, mage.cards.r.ReconstructedThopter.class)); cards.add(new SetCardInfo("Recruitment Officer", 23, Rarity.UNCOMMON, mage.cards.r.RecruitmentOfficer.class)); cards.add(new SetCardInfo("Rust Goliath", 204, Rarity.COMMON, mage.cards.r.RustGoliath.class)); From fc560d48533b513b89f2ed0079927f682a44b18e Mon Sep 17 00:00:00 2001 From: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com> Date: Thu, 3 Nov 2022 02:10:26 +0000 Subject: [PATCH 2/3] Standardise use of CantBeCounteredSourceAbility for remaining cards not yet using it --- Mage.Sets/src/mage/cards/a/AbruptDecay.java | 14 +++----------- Mage.Sets/src/mage/cards/o/OverwhelmingDenial.java | 14 +++----------- Mage.Sets/src/mage/cards/r/RazeToTheGround.java | 11 ++--------- Mage.Sets/src/mage/cards/s/SlaughterGames.java | 13 +++---------- Mage.Sets/src/mage/cards/t/TearsOfValakut.java | 14 +++----------- Mage.Sets/src/mage/cards/u/UrzasRage.java | 14 +++----------- 6 files changed, 17 insertions(+), 63 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AbruptDecay.java b/Mage.Sets/src/mage/cards/a/AbruptDecay.java index 5e10f06f22c..18792c6d0c7 100644 --- a/Mage.Sets/src/mage/cards/a/AbruptDecay.java +++ b/Mage.Sets/src/mage/cards/a/AbruptDecay.java @@ -2,16 +2,12 @@ package mage.cards.a; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; -import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.target.common.TargetNonlandPermanent; @@ -31,12 +27,8 @@ public final class AbruptDecay extends CardImpl { public AbruptDecay(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{G}"); - // Abrupt Decay can't be countered. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); // Destroy target nonland permanent with converted mana cost 3 or less. this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/o/OverwhelmingDenial.java b/Mage.Sets/src/mage/cards/o/OverwhelmingDenial.java index 4e828b4eea0..1571b1473e1 100644 --- a/Mage.Sets/src/mage/cards/o/OverwhelmingDenial.java +++ b/Mage.Sets/src/mage/cards/o/OverwhelmingDenial.java @@ -2,16 +2,12 @@ package mage.cards.o; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.keyword.SurgeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; import mage.target.TargetSpell; /** @@ -23,12 +19,8 @@ public final class OverwhelmingDenial extends CardImpl { public OverwhelmingDenial(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}{U}"); - // Overwhelming Denial can't be countered by spell or abilities. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); // Counter target spell. this.getSpellAbility().addTarget(new TargetSpell()); diff --git a/Mage.Sets/src/mage/cards/r/RazeToTheGround.java b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java index f3f7f6473b6..fa17ed9243b 100644 --- a/Mage.Sets/src/mage/cards/r/RazeToTheGround.java +++ b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java @@ -1,15 +1,12 @@ package mage.cards.r; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -26,11 +23,7 @@ public final class RazeToTheGround extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // This spell can't be countered. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + this.addAbility(new CantBeCounteredSourceAbility()); // Destroy target artifact. If its mana value was 1 or less, draw a card. this.getSpellAbility().addEffect(new RazeToTheGroundEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SlaughterGames.java b/Mage.Sets/src/mage/cards/s/SlaughterGames.java index a78aead43cc..810f8d53a69 100644 --- a/Mage.Sets/src/mage/cards/s/SlaughterGames.java +++ b/Mage.Sets/src/mage/cards/s/SlaughterGames.java @@ -1,15 +1,12 @@ package mage.cards.s; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; import mage.game.Game; import mage.target.common.TargetOpponent; @@ -23,12 +20,8 @@ public final class SlaughterGames extends CardImpl { public SlaughterGames(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); - // Slaughter Games can't be countered. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); // Name a nonland card. Search target opponent's graveyard, hand, and library for any number of cards with that name and exile them. Then that player shuffles their library. this.getSpellAbility().addEffect(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME)); diff --git a/Mage.Sets/src/mage/cards/t/TearsOfValakut.java b/Mage.Sets/src/mage/cards/t/TearsOfValakut.java index bab112c6321..ec8c711b7e8 100644 --- a/Mage.Sets/src/mage/cards/t/TearsOfValakut.java +++ b/Mage.Sets/src/mage/cards/t/TearsOfValakut.java @@ -2,16 +2,12 @@ package mage.cards.t; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.target.common.TargetCreaturePermanent; @@ -31,12 +27,8 @@ public final class TearsOfValakut extends CardImpl { public TearsOfValakut(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); - // Tears of Valakut can't be countered. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); // Tears of Valakut deals 5 damage to target creature with flying. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/u/UrzasRage.java b/Mage.Sets/src/mage/cards/u/UrzasRage.java index 681fc5fa84c..78ef1ae873a 100644 --- a/Mage.Sets/src/mage/cards/u/UrzasRage.java +++ b/Mage.Sets/src/mage/cards/u/UrzasRage.java @@ -1,17 +1,13 @@ package mage.cards.u; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CantBeCounteredSourceEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; import mage.target.common.TargetAnyTarget; import java.util.UUID; @@ -27,12 +23,8 @@ public final class UrzasRage extends CardImpl { // Kicker {8}{R} this.addAbility(new KickerAbility("{8}{R}")); - // Urza's Rage can't be countered. - Effect effect = new CantBeCounteredSourceEffect(); - effect.setText("this spell can't be countered"); - Ability ability = new SimpleStaticAbility(Zone.STACK, effect); - ability.setRuleAtTheTop(true); - this.addAbility(ability); + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); // Urza's Rage deals 3 damage to any target. If Urza's Rage was kicked, instead it deals 10 damage to that creature or player and the damage can't be prevented. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( From dafbf1b8965afedd4060f901442beab84da7b6d4 Mon Sep 17 00:00:00 2001 From: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com> Date: Thu, 3 Nov 2022 20:02:07 +0000 Subject: [PATCH 3/3] Reapplied setRuleAtTheTop to necessary cards --- Mage.Sets/src/mage/cards/a/AbruptDecay.java | 2 +- Mage.Sets/src/mage/cards/r/RazeToTheGround.java | 2 +- Mage.Sets/src/mage/cards/s/SlaughterGames.java | 2 +- Mage.Sets/src/mage/cards/t/TearsOfValakut.java | 2 +- Mage.Sets/src/mage/cards/u/UrzasRage.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AbruptDecay.java b/Mage.Sets/src/mage/cards/a/AbruptDecay.java index 18792c6d0c7..5a46ad39be8 100644 --- a/Mage.Sets/src/mage/cards/a/AbruptDecay.java +++ b/Mage.Sets/src/mage/cards/a/AbruptDecay.java @@ -28,7 +28,7 @@ public final class AbruptDecay extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{G}"); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.addAbility(new CantBeCounteredSourceAbility().setRuleAtTheTop(true)); // Destroy target nonland permanent with converted mana cost 3 or less. this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/r/RazeToTheGround.java b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java index fa17ed9243b..53add0684db 100644 --- a/Mage.Sets/src/mage/cards/r/RazeToTheGround.java +++ b/Mage.Sets/src/mage/cards/r/RazeToTheGround.java @@ -23,7 +23,7 @@ public final class RazeToTheGround extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.addAbility(new CantBeCounteredSourceAbility().setRuleAtTheTop(true)); // Destroy target artifact. If its mana value was 1 or less, draw a card. this.getSpellAbility().addEffect(new RazeToTheGroundEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SlaughterGames.java b/Mage.Sets/src/mage/cards/s/SlaughterGames.java index 810f8d53a69..b5aed40c69b 100644 --- a/Mage.Sets/src/mage/cards/s/SlaughterGames.java +++ b/Mage.Sets/src/mage/cards/s/SlaughterGames.java @@ -21,7 +21,7 @@ public final class SlaughterGames extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.addAbility(new CantBeCounteredSourceAbility().setRuleAtTheTop(true)); // Name a nonland card. Search target opponent's graveyard, hand, and library for any number of cards with that name and exile them. Then that player shuffles their library. this.getSpellAbility().addEffect(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME)); diff --git a/Mage.Sets/src/mage/cards/t/TearsOfValakut.java b/Mage.Sets/src/mage/cards/t/TearsOfValakut.java index ec8c711b7e8..7fb39717873 100644 --- a/Mage.Sets/src/mage/cards/t/TearsOfValakut.java +++ b/Mage.Sets/src/mage/cards/t/TearsOfValakut.java @@ -28,7 +28,7 @@ public final class TearsOfValakut extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.addAbility(new CantBeCounteredSourceAbility().setRuleAtTheTop(true)); // Tears of Valakut deals 5 damage to target creature with flying. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/u/UrzasRage.java b/Mage.Sets/src/mage/cards/u/UrzasRage.java index 78ef1ae873a..cd87a10bf6e 100644 --- a/Mage.Sets/src/mage/cards/u/UrzasRage.java +++ b/Mage.Sets/src/mage/cards/u/UrzasRage.java @@ -24,7 +24,7 @@ public final class UrzasRage extends CardImpl { this.addAbility(new KickerAbility("{8}{R}")); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.addAbility(new CantBeCounteredSourceAbility().setRuleAtTheTop(true)); // Urza's Rage deals 3 damage to any target. If Urza's Rage was kicked, instead it deals 10 damage to that creature or player and the damage can't be prevented. this.getSpellAbility().addEffect(new ConditionalOneShotEffect(