From 48d7d07f939650dde59aefa8425306a037269e03 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Thu, 21 Sep 2023 23:46:09 -0400 Subject: [PATCH] reimplement Fractured Loyalty --- .../src/mage/cards/f/FracturedLoyalty.java | 132 +++++++----------- .../src/mage/cards/s/SpectralPrison.java | 7 +- ...BecomesTargetAttachedTriggeredAbility.java | 26 +++- 3 files changed, 73 insertions(+), 92 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java index 7e4cebd0d2f..2dc7d19d79a 100644 --- a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java +++ b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java @@ -2,7 +2,7 @@ package mage.cards.f; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BecomesTargetAttachedTriggeredAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; @@ -11,8 +11,8 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; @@ -37,7 +37,9 @@ public final class FracturedLoyalty extends CardImpl { this.addAbility(ability); // Whenever enchanted creature becomes the target of a spell or ability, that spell or ability's controller gains control of that creature. - this.addAbility(new FracturedLoyaltyTriggeredAbility()); + this.addAbility(new BecomesTargetAttachedTriggeredAbility(new FracturedLoyaltyEffect(), + StaticFilters.FILTER_SPELL_OR_ABILITY_A, SetTargetPointer.PLAYER, false) + .setTriggerPhrase("Whenever enchanted creature becomes the target of a spell or ability, ")); } private FracturedLoyalty(final FracturedLoyalty card) { @@ -49,85 +51,47 @@ public final class FracturedLoyalty extends CardImpl { return new FracturedLoyalty(this); } - private static class FracturedLoyaltyEffect extends OneShotEffect { - - FracturedLoyaltyEffect() { - super(Outcome.GainControl); - this.staticText = "that spell or ability's controller gains control of that creature"; - } - - private FracturedLoyaltyEffect(final FracturedLoyaltyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - // In the case that Fractured Loyalty is blinked - Permanent enchantment = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (enchantment == null) { - // It was not blinked, use the standard method - enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); - } - if (enchantment != null) { - Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); - if (enchantedCreature != null) { - Player controller = game.getPlayer(enchantedCreature.getControllerId()); - if (enchantment.getAttachedTo() != null) { - if (controller != null && !enchantedCreature.isControlledBy(this.getTargetPointer().getFirst(game, source))) { - ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, this.getTargetPointer().getFirst(game, source)); - effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo(), game)); - game.addEffect(effect, source); - return true; - } - } - } - } - return false; - } - - @Override - public FracturedLoyaltyEffect copy() { - return new FracturedLoyaltyEffect(this); - } - - } - - class FracturedLoyaltyTriggeredAbility extends TriggeredAbilityImpl { - - public FracturedLoyaltyTriggeredAbility() { - super(Zone.BATTLEFIELD, new FracturedLoyaltyEffect(), false); - } - - private FracturedLoyaltyTriggeredAbility(final FracturedLoyaltyTriggeredAbility ability) { - super(ability); - } - - @Override - public FracturedLoyaltyTriggeredAbility copy() { - return new FracturedLoyaltyTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TARGETED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanentOrLKIBattlefield(this.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); - if (enchantedCreature != null && event.getTargetId().equals(enchantment.getAttachedTo())) { - getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever enchanted creature becomes the target of a spell or ability, that spell or ability's controller gains control of that creature."; - } - } +} + +class FracturedLoyaltyEffect extends OneShotEffect { + + FracturedLoyaltyEffect() { + super(Outcome.GainControl); + this.staticText = "that spell or ability's controller gains control of that creature"; + } + + private FracturedLoyaltyEffect(final FracturedLoyaltyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + // In the case that Fractured Loyalty is blinked + Permanent enchantment = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); + if (enchantment == null) { + // It was not blinked, use the standard method + enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); + } + if (enchantment == null || enchantment.getAttachedTo() == null) { + return false; + } + Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); + if (enchantedCreature == null) { + return false; + } + Player controller = game.getPlayer(enchantedCreature.getControllerId()); + if (controller != null && !enchantedCreature.isControlledBy(this.getTargetPointer().getFirst(game, source))) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, this.getTargetPointer().getFirst(game, source)); + effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo(), game)); + game.addEffect(effect, source); + return true; + } + return false; + } + + @Override + public FracturedLoyaltyEffect copy() { + return new FracturedLoyaltyEffect(this); + } + } diff --git a/Mage.Sets/src/mage/cards/s/SpectralPrison.java b/Mage.Sets/src/mage/cards/s/SpectralPrison.java index 72b67c6d566..2268f6ac827 100644 --- a/Mage.Sets/src/mage/cards/s/SpectralPrison.java +++ b/Mage.Sets/src/mage/cards/s/SpectralPrison.java @@ -9,10 +9,7 @@ import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.StaticFilters; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -37,7 +34,7 @@ public final class SpectralPrison extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); // When enchanted creature becomes the target of a spell, sacrifice Spectral Prison. - this.addAbility(new BecomesTargetAttachedTriggeredAbility(new SacrificeSourceEffect(), StaticFilters.FILTER_SPELL_A, false)); + this.addAbility(new BecomesTargetAttachedTriggeredAbility(new SacrificeSourceEffect(), StaticFilters.FILTER_SPELL_A, SetTargetPointer.NONE, false)); } private SpectralPrison(final SpectralPrison card) { diff --git a/Mage/src/main/java/mage/abilities/common/BecomesTargetAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesTargetAttachedTriggeredAbility.java index 4b619a2ae7b..264942e928e 100644 --- a/Mage/src/main/java/mage/abilities/common/BecomesTargetAttachedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BecomesTargetAttachedTriggeredAbility.java @@ -2,6 +2,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterStackObject; import mage.filter.StaticFilters; @@ -9,6 +10,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.stack.StackObject; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; /** @@ -17,20 +19,23 @@ import mage.util.CardUtil; public class BecomesTargetAttachedTriggeredAbility extends TriggeredAbilityImpl { private final FilterStackObject filter; + private final SetTargetPointer setTargetPointer; public BecomesTargetAttachedTriggeredAbility(Effect effect) { - this(effect, StaticFilters.FILTER_SPELL_OR_ABILITY_A, false); + this(effect, StaticFilters.FILTER_SPELL_OR_ABILITY_A, SetTargetPointer.NONE, false); } - public BecomesTargetAttachedTriggeredAbility(Effect effect, FilterStackObject filter, boolean optional) { + public BecomesTargetAttachedTriggeredAbility(Effect effect, FilterStackObject filter, SetTargetPointer setTargetPointer, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); this.filter = filter; + this.setTargetPointer = setTargetPointer; setTriggerPhrase("When enchanted creature becomes the target of " + filter.getMessage() + ", "); } protected BecomesTargetAttachedTriggeredAbility(final BecomesTargetAttachedTriggeredAbility ability) { super(ability); this.filter = ability.filter; + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -53,6 +58,21 @@ public class BecomesTargetAttachedTriggeredAbility extends TriggeredAbilityImpl if (targetingObject == null || !filter.match(targetingObject, getControllerId(), this, game)) { return false; } - return CardUtil.checkTargetMap(this.id, targetingObject, event, game); + if (!CardUtil.checkTargetMap(this.id, targetingObject, event, game)) { + return false; + } + switch (setTargetPointer) { + case PLAYER: + this.getAllEffects().setTargetPointer(new FixedTarget(targetingObject.getControllerId(), game)); + break; + case SPELL: + this.getAllEffects().setTargetPointer(new FixedTarget(targetingObject.getId())); + break; + case NONE: + break; + default: + throw new IllegalArgumentException("Unsupported SetTargetPointer in BecomesTargetAttachedTriggeredAbility"); + } + return true; } }