From c75431f27be3e4e0cec9cde0ea8ab5f2de747ae1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 3 Feb 2022 19:58:58 -0500 Subject: [PATCH] [NEO] Implemented Weaver of Harmony --- Mage.Sets/src/mage/cards/a/AyeshaTanaka.java | 2 +- Mage.Sets/src/mage/cards/b/BrownOuphe.java | 2 +- Mage.Sets/src/mage/cards/o/OupheVandals.java | 2 +- Mage.Sets/src/mage/cards/r/Rust.java | 2 +- .../src/mage/cards/s/StrionicResonator.java | 22 ++-- .../mage/cards/t/TawnosUrzasApprentice.java | 2 +- .../src/mage/cards/w/WeaverOfHarmony.java | 108 ++++++++++++++++++ .../src/mage/sets/KamigawaNeonDynasty.java | 1 + .../other/ArtifactSourcePredicate.java | 15 +-- 9 files changed, 125 insertions(+), 31 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/w/WeaverOfHarmony.java diff --git a/Mage.Sets/src/mage/cards/a/AyeshaTanaka.java b/Mage.Sets/src/mage/cards/a/AyeshaTanaka.java index 02ab49e6904..159ba11a224 100644 --- a/Mage.Sets/src/mage/cards/a/AyeshaTanaka.java +++ b/Mage.Sets/src/mage/cards/a/AyeshaTanaka.java @@ -28,7 +28,7 @@ public final class AyeshaTanaka extends CardImpl { private static final FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { - filter.add(new ArtifactSourcePredicate()); + filter.add(ArtifactSourcePredicate.instance); } public AyeshaTanaka(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/b/BrownOuphe.java b/Mage.Sets/src/mage/cards/b/BrownOuphe.java index 3fa7fdc17ef..b3f9d7ff462 100644 --- a/Mage.Sets/src/mage/cards/b/BrownOuphe.java +++ b/Mage.Sets/src/mage/cards/b/BrownOuphe.java @@ -26,7 +26,7 @@ public final class BrownOuphe extends CardImpl { private static final FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { - filter.add(new ArtifactSourcePredicate()); + filter.add(ArtifactSourcePredicate.instance); } public BrownOuphe(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/o/OupheVandals.java b/Mage.Sets/src/mage/cards/o/OupheVandals.java index e6befc1402b..9da7376ba67 100644 --- a/Mage.Sets/src/mage/cards/o/OupheVandals.java +++ b/Mage.Sets/src/mage/cards/o/OupheVandals.java @@ -30,7 +30,7 @@ public final class OupheVandals extends CardImpl { private static final FilterStackObject filter = new FilterStackObject("ability from an artifact source"); static { - filter.add(new ArtifactSourcePredicate()); + filter.add(ArtifactSourcePredicate.instance); } public OupheVandals(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/r/Rust.java b/Mage.Sets/src/mage/cards/r/Rust.java index 2ff86879a7f..f85855cf8af 100644 --- a/Mage.Sets/src/mage/cards/r/Rust.java +++ b/Mage.Sets/src/mage/cards/r/Rust.java @@ -19,7 +19,7 @@ public final class Rust extends CardImpl { private static final FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { - filter.add(new ArtifactSourcePredicate()); + filter.add(ArtifactSourcePredicate.instance); } public Rust(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/s/StrionicResonator.java b/Mage.Sets/src/mage/cards/s/StrionicResonator.java index 23817a78163..df7808e549e 100644 --- a/Mage.Sets/src/mage/cards/s/StrionicResonator.java +++ b/Mage.Sets/src/mage/cards/s/StrionicResonator.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; @@ -12,15 +10,13 @@ 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.game.stack.StackAbility; -import mage.players.Player; import mage.target.common.TargetTriggeredAbility; +import java.util.UUID; + /** - * * @author Plopman */ public final class StrionicResonator extends CardImpl { @@ -29,7 +25,7 @@ public final class StrionicResonator extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // {2}, {T}: Copy target triggered ability you control. You may choose new targets for the copy. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StrionicResonatorEffect(), new ManaCostsImpl("{2}")); + Ability ability = new SimpleActivatedAbility(new StrionicResonatorEffect(), new ManaCostsImpl<>("{2}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetTriggeredAbility()); this.addAbility(ability); @@ -58,15 +54,11 @@ class StrionicResonatorEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(targetPointer.getFirst(game, source)); - if (stackAbility != null) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (controller != null && sourcePermanent != null) { - stackAbility.createCopyOnStack(game, source, source.getControllerId(), true); - return true; - } + if (stackAbility == null) { + return false; } - return false; + stackAbility.createCopyOnStack(game, source, source.getControllerId(), true); + return true; } diff --git a/Mage.Sets/src/mage/cards/t/TawnosUrzasApprentice.java b/Mage.Sets/src/mage/cards/t/TawnosUrzasApprentice.java index df79e5c7d40..0e3fe8681a8 100644 --- a/Mage.Sets/src/mage/cards/t/TawnosUrzasApprentice.java +++ b/Mage.Sets/src/mage/cards/t/TawnosUrzasApprentice.java @@ -33,7 +33,7 @@ public final class TawnosUrzasApprentice extends CardImpl { private static final FilterStackObject filter = new FilterStackObject("activated or triggered ability you control from an artifact source"); static { - filter.add(new ArtifactSourcePredicate()); + filter.add(ArtifactSourcePredicate.instance); filter.add(TargetController.YOU.getControllerPredicate()); } diff --git a/Mage.Sets/src/mage/cards/w/WeaverOfHarmony.java b/Mage.Sets/src/mage/cards/w/WeaverOfHarmony.java new file mode 100644 index 00000000000..4285daf1d1c --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WeaverOfHarmony.java @@ -0,0 +1,108 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterStackObject; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.target.TargetStackObject; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WeaverOfHarmony extends CardImpl { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("enchantment creatures"); + private static final FilterStackObject filter2 + = new FilterStackObject("activated or triggered ability you control from an enchantment source"); + + static { + filter.add(CardType.ENCHANTMENT.getPredicate()); + filter2.add(WeaverOfHarmonyPredicate.instance); + } + + public WeaverOfHarmony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.SNAKE); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Other enchantment creatures you control get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, filter, true + ))); + + // {G}, {T}: Copy target activated or triggered ability you control from an enchantment source. You may choose new targets for the copy. + Ability ability = new SimpleActivatedAbility(new WeaverOfHarmonyEffect(), new ManaCostsImpl<>("{G}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetStackObject(filter2)); + this.addAbility(ability); + } + + private WeaverOfHarmony(final WeaverOfHarmony card) { + super(card); + } + + @Override + public WeaverOfHarmony copy() { + return new WeaverOfHarmony(this); + } +} + +enum WeaverOfHarmonyPredicate implements Predicate { + instance; + + @Override + public boolean apply(StackObject input, Game game) { + return input instanceof StackAbility + && ((StackAbility) input).getSourceObject(game).isEnchantment(game); + } +} + +class WeaverOfHarmonyEffect extends OneShotEffect { + + WeaverOfHarmonyEffect() { + super(Outcome.Benefit); + staticText = "copy target activated or triggered ability you control " + + "from an enchantment source. You may choose new targets for the copy"; + } + + private WeaverOfHarmonyEffect(final WeaverOfHarmonyEffect effect) { + super(effect); + } + + @Override + public WeaverOfHarmonyEffect copy() { + return new WeaverOfHarmonyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(targetPointer.getFirst(game, source)); + if (stackAbility == null) { + return false; + } + stackAbility.createCopyOnStack(game, source, source.getControllerId(), true); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java index a1f9be3ceff..826278c11d7 100644 --- a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java +++ b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java @@ -157,6 +157,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Vector Glider", 66, Rarity.COMMON, mage.cards.v.VectorGlider.class)); cards.add(new SetCardInfo("Vision of the Unspeakable", 48, Rarity.UNCOMMON, mage.cards.v.VisionOfTheUnspeakable.class)); cards.add(new SetCardInfo("Walking Skyscraper", 263, Rarity.UNCOMMON, mage.cards.w.WalkingSkyscraper.class)); + cards.add(new SetCardInfo("Weaver of Harmony", 213, Rarity.RARE, mage.cards.w.WeaverOfHarmony.class)); cards.add(new SetCardInfo("You Are Already Dead", 129, Rarity.COMMON, mage.cards.y.YouAreAlreadyDead.class)); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); // remove when mechanic is fully implemented diff --git a/Mage/src/main/java/mage/filter/predicate/other/ArtifactSourcePredicate.java b/Mage/src/main/java/mage/filter/predicate/other/ArtifactSourcePredicate.java index 26ffd732330..3e98d6a14b6 100644 --- a/Mage/src/main/java/mage/filter/predicate/other/ArtifactSourcePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/other/ArtifactSourcePredicate.java @@ -1,4 +1,3 @@ - package mage.filter.predicate.other; import mage.filter.predicate.Predicate; @@ -7,21 +6,15 @@ import mage.game.stack.StackAbility; import mage.game.stack.StackObject; /** - * * @author LevelX2 */ -public class ArtifactSourcePredicate implements Predicate { - - public ArtifactSourcePredicate() { - } +public enum ArtifactSourcePredicate implements Predicate { + instance; @Override public boolean apply(StackObject input, Game game) { - if (input instanceof StackAbility) { - StackAbility ability = (StackAbility) input; - return ability.getSourceObject(game).isArtifact(game); - } - return false; + return input instanceof StackAbility + && ((StackAbility) input).getSourceObject(game).isArtifact(game); } @Override