From 549c9cb86389ea932c828cb183e2aca6e332b48f Mon Sep 17 00:00:00 2001 From: xenohedron Date: Fri, 4 Aug 2023 22:14:53 -0400 Subject: [PATCH] new DefendingPlayerControlsAttachedAttackingPredicate cleanup Heart-Piercer Bow fix Lothlorien Blade --- .../src/mage/cards/g/GreatswordOfTyr.java | 26 +------ .../src/mage/cards/h/HeartPiercerBow.java | 68 ++++--------------- .../src/mage/cards/l/LothlorienBlade.java | 48 +++++++------ ...yerControlsAttachedAttackingPredicate.java | 34 ++++++++++ 4 files changed, 80 insertions(+), 96 deletions(-) create mode 100644 Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerControlsAttachedAttackingPredicate.java diff --git a/Mage.Sets/src/mage/cards/g/GreatswordOfTyr.java b/Mage.Sets/src/mage/cards/g/GreatswordOfTyr.java index 8fb67ff0454..37cc560f98e 100644 --- a/Mage.Sets/src/mage/cards/g/GreatswordOfTyr.java +++ b/Mage.Sets/src/mage/cards/g/GreatswordOfTyr.java @@ -14,13 +14,9 @@ import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.ObjectSourcePlayer; -import mage.filter.predicate.ObjectSourcePlayerPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsAttachedAttackingPredicate; import mage.target.TargetPermanent; -import java.util.Optional; import java.util.UUID; /** @@ -31,7 +27,7 @@ public final class GreatswordOfTyr extends CardImpl { private static final FilterPermanent filter = new FilterCreaturePermanent("creature defending player controls"); static { - filter.add(GreatswordOfTyrPredicate.instance); + filter.add(DefendingPlayerControlsAttachedAttackingPredicate.instance); } public GreatswordOfTyr(UUID ownerId, CardSetInfo setInfo) { @@ -60,21 +56,3 @@ public final class GreatswordOfTyr extends CardImpl { return new GreatswordOfTyr(this); } } - -enum GreatswordOfTyrPredicate implements ObjectSourcePlayerPredicate { - instance; - - @Override - public boolean apply(ObjectSourcePlayer input, Game game) { - return Optional.ofNullable(input.getSource().getSourcePermanentOrLKI(game)) - .map(Permanent::getAttachedTo) - .map(uuid -> game.getCombat().getDefendingPlayerId(uuid, game)) - .map(input.getObject()::isControlledBy) - .orElse(false); - } - - @Override - public String toString() { - return ""; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HeartPiercerBow.java b/Mage.Sets/src/mage/cards/h/HeartPiercerBow.java index b4e8f8cb239..72b32c2cd14 100644 --- a/Mage.Sets/src/mage/cards/h/HeartPiercerBow.java +++ b/Mage.Sets/src/mage/cards/h/HeartPiercerBow.java @@ -1,36 +1,40 @@ - package mage.cards.h; -import java.util.UUID; +import mage.abilities.Ability; import mage.abilities.common.AttacksAttachedTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsAttachedAttackingPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * - * @author LevelX2 + * @author xenohedron */ public final class HeartPiercerBow extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + + static { + filter.add(DefendingPlayerControlsAttachedAttackingPredicate.instance); + } + public HeartPiercerBow(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); this.subtype.add(SubType.EQUIPMENT); // Whenever equipped creature attacks, Heart-Piercer Bow deals 1 damage to target creature defending player controls. - this.addAbility(new HeartPiercerBowAbility()); + Ability ability = new AttacksAttachedTriggeredAbility(new DamageTargetEffect(1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); // Equip {1} this.addAbility(new EquipAbility(Outcome.Benefit, new GenericManaCost(1))); @@ -40,50 +44,8 @@ public final class HeartPiercerBow extends CardImpl { super(card); } - - @Override public HeartPiercerBow copy() { return new HeartPiercerBow(this); } } - -class HeartPiercerBowAbility extends AttacksAttachedTriggeredAbility { - - public HeartPiercerBowAbility() { - super(new DamageTargetEffect(1), AttachmentType.EQUIPMENT, false); - } - - public HeartPiercerBowAbility(final HeartPiercerBowAbility ability) { - super(ability); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (super.checkTrigger(event, game)) { - Permanent equipment = game.getPermanent(getSourceId()); - if (equipment != null && equipment.getAttachedTo() != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); - UUID defenderId = game.getCombat().getDefendingPlayerId(equipment.getAttachedTo(), game); - if (defenderId != null) { - filter.add(new ControllerIdPredicate(defenderId)); - this.getTargets().clear(); - TargetCreaturePermanent target = new TargetCreaturePermanent(filter); - this.addTarget(target); - return true; - } - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever equipped creature attacks, {this} deals 1 damage to target creature defending player controls."; - } - - @Override - public HeartPiercerBowAbility copy() { - return new HeartPiercerBowAbility(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/l/LothlorienBlade.java b/Mage.Sets/src/mage/cards/l/LothlorienBlade.java index 53fac8be30c..bb1dbec9197 100644 --- a/Mage.Sets/src/mage/cards/l/LothlorienBlade.java +++ b/Mage.Sets/src/mage/cards/l/LothlorienBlade.java @@ -3,8 +3,7 @@ package mage.cards.l; import mage.abilities.Ability; import mage.abilities.common.AttacksAttachedTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.common.AttachedPermanentPowerCount; -import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,14 +12,12 @@ import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.ObjectSourcePlayer; -import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.filter.predicate.permanent.DefendingPlayerControlsAttachedAttackingPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; -import java.util.Optional; import java.util.UUID; /** @@ -32,7 +29,7 @@ public final class LothlorienBlade extends CardImpl { private static final FilterControlledCreaturePermanent filterElf = new FilterControlledCreaturePermanent(SubType.ELF, "Elf"); static { - filter.add(LothlorienBladePredicate.instance); + filter.add(DefendingPlayerControlsAttachedAttackingPredicate.instance); } public LothlorienBlade(UUID ownerId, CardSetInfo setInfo) { @@ -41,8 +38,7 @@ public final class LothlorienBlade extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Whenever equipped creature attacks, it deals damage equal to its power to target creature defending player controls. - Ability ability = new AttacksAttachedTriggeredAbility(new DamageTargetEffect(AttachedPermanentPowerCount.instance) - .setText("it deals damage equal to its power to target creature defending player controls")); + Ability ability = new AttacksAttachedTriggeredAbility(new LothlorienBladeEffect()); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); @@ -64,20 +60,34 @@ public final class LothlorienBlade extends CardImpl { } } -enum LothlorienBladePredicate implements ObjectSourcePlayerPredicate { - instance; +class LothlorienBladeEffect extends OneShotEffect { - @Override - public boolean apply(ObjectSourcePlayer input, Game game) { - return Optional.ofNullable(input.getSource().getSourcePermanentOrLKI(game)) - .map(Permanent::getAttachedTo) - .map(uuid -> game.getCombat().getDefendingPlayerId(uuid, game)) - .map(input.getObject()::isControlledBy) - .orElse(false); + LothlorienBladeEffect() { + super(Outcome.Damage); + staticText = "it deals damage equal to its power to target creature defending player controls"; + } + + private LothlorienBladeEffect(final LothlorienBladeEffect effect) { + super(effect); } @Override - public String toString() { - return ""; + public LothlorienBladeEffect copy() { + return new LothlorienBladeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent equipment = source.getSourcePermanentOrLKI(game); + if (targetCreature == null || equipment == null) { + return false; + } + Permanent attacker = game.getPermanentOrLKIBattlefield(equipment.getAttachedTo()); + if (attacker == null) { + return false; + } + targetCreature.damage(attacker.getPower().getValue(), attacker.getId(), source, game); + return true; } } diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerControlsAttachedAttackingPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerControlsAttachedAttackingPredicate.java new file mode 100644 index 00000000000..d58a6350439 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerControlsAttachedAttackingPredicate.java @@ -0,0 +1,34 @@ +package mage.filter.predicate.permanent; + +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.Optional; + +/** + * This predicate can only apply when source is attached to an attacking creature. + *

+ * It should be used when the source is attached to an attacking creature during an effect + * e.g. "Whenever equipped creature attacks, tap target creature defending player controls." + * + * @author Susucr, TheElk801, xenohedron + */ +public enum DefendingPlayerControlsAttachedAttackingPredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return Optional.ofNullable(input.getSource().getSourcePermanentOrLKI(game)) + .map(Permanent::getAttachedTo) + .map(uuid -> game.getCombat().getDefendingPlayerId(uuid, game)) + .map(input.getObject()::isControlledBy) + .orElse(false); + } + + @Override + public String toString() { + return ""; + } +}