From 5736b00f0f92e2dbeb00ad88de25b2459a16909c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 23 Feb 2021 09:44:26 -0500 Subject: [PATCH] combined "enchanted player's upkeep" triggers into one class --- Mage.Sets/src/mage/cards/c/CruelReality.java | 99 ++++++------------- .../src/mage/cards/c/CurseOfOblivion.java | 46 +-------- .../mage/cards/c/CurseOfTheBloodyTome.java | 54 +--------- .../mage/cards/c/CurseOfThePiercedHeart.java | 89 ++++------------- Mage.Sets/src/mage/cards/c/CurseOfThirst.java | 90 ++++------------- .../src/mage/cards/i/InfectiousCurse.java | 57 ++--------- .../src/mage/cards/t/TormentOfScarabs.java | 92 +++++------------ ...nningOfUpkeepAttachedTriggeredAbility.java | 52 ++++++++++ 8 files changed, 160 insertions(+), 419 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepAttachedTriggeredAbility.java diff --git a/Mage.Sets/src/mage/cards/c/CruelReality.java b/Mage.Sets/src/mage/cards/c/CruelReality.java index 856f688834f..7f354276433 100644 --- a/Mage.Sets/src/mage/cards/c/CruelReality.java +++ b/Mage.Sets/src/mage/cards/c/CruelReality.java @@ -1,8 +1,7 @@ - package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; @@ -11,22 +10,18 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** - * * @author jeffwadsworth */ public final class CruelReality extends CardImpl { @@ -43,8 +38,7 @@ public final class CruelReality extends CardImpl { this.addAbility(new EnchantAbility(auraTarget.getTargetName())); //At the beginning of enchanted player's upkeep, that player sacrifices a creature or planeswalker. If the player can't, they lose 5 life. - this.addAbility(new CruelRealityTriggeredAbiilty()); - + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility(new CruelRealityEffect())); } private CruelReality(final CruelReality card) { @@ -57,55 +51,23 @@ public final class CruelReality extends CardImpl { } } -class CruelRealityTriggeredAbiilty extends TriggeredAbilityImpl { - - public CruelRealityTriggeredAbiilty() { - super(Zone.BATTLEFIELD, new CruelRealityEffect()); - } - - public CruelRealityTriggeredAbiilty(final CruelRealityTriggeredAbiilty ability) { - super(ability); - } - - @Override - public CruelRealityTriggeredAbiilty copy() { - return new CruelRealityTriggeredAbiilty(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.sourceId); - if (enchantment != null - && enchantment.getAttachedTo() != null) { - Player cursedPlayer = game.getPlayer(enchantment.getAttachedTo()); - if (cursedPlayer != null - && game.isActivePlayer(cursedPlayer.getId())) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(cursedPlayer.getId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, " + super.getRule(); - } -} - class CruelRealityEffect extends OneShotEffect { - public CruelRealityEffect() { + private static final FilterPermanent filter = new FilterControlledPermanent("creature or planeswalker"); + + static { + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.PLANESWALKER.getPredicate() + )); + } + + CruelRealityEffect() { super(Outcome.LoseLife); staticText = "that player sacrifices a creature or planeswalker. If the player can't, they lose 5 life"; } - public CruelRealityEffect(final CruelRealityEffect effect) { + private CruelRealityEffect(final CruelRealityEffect effect) { super(effect); } @@ -118,24 +80,21 @@ class CruelRealityEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player cursedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (cursedPlayer != null - && controller != null) { - FilterControlledPermanent filter = new FilterControlledPermanent("creature or planeswalker"); - filter.add(Predicates.or( - CardType.CREATURE.getPredicate(), - CardType.PLANESWALKER.getPredicate())); - TargetPermanent target = new TargetPermanent(filter); - if (cursedPlayer.choose(Outcome.Sacrifice, target, source.getId(), game)) { - Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget()); - if (objectToBeSacrificed != null) { - if (objectToBeSacrificed.sacrifice(source, game)) { - return true; - } - } - } - cursedPlayer.loseLife(5, game, source, false); - return true; + if (cursedPlayer == null || controller == null) { + return false; } - return false; + TargetPermanent target = new TargetPermanent(filter); + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), cursedPlayer.getId(), game) + && cursedPlayer.choose(Outcome.Sacrifice, target, source.getId(), game)) { + Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget()); + if (objectToBeSacrificed != null) { + if (objectToBeSacrificed.sacrifice(source, game)) { + return true; + } + } + } + cursedPlayer.loseLife(5, game, source, false); + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java index 50bc54adeb7..62eec2c2e5c 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java @@ -1,7 +1,7 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ExileFromZoneTargetEffect; import mage.abilities.keyword.EnchantAbility; @@ -12,11 +12,7 @@ import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -37,7 +33,9 @@ public final class CurseOfOblivion extends CardImpl { this.addAbility(ability); // At the beginning of enchanted player's upkeep, that player exiles two cards from their graveyard. - this.addAbility(new CurseOfOblivionAbility()); + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility(new ExileFromZoneTargetEffect( + Zone.GRAVEYARD, StaticFilters.FILTER_CARD_CARDS, 2, false + ).setText("that player exiles two cards from their graveyard"))); } private CurseOfOblivion(final CurseOfOblivion card) { @@ -49,39 +47,3 @@ public final class CurseOfOblivion extends CardImpl { return new CurseOfOblivion(this); } } - -class CurseOfOblivionAbility extends TriggeredAbilityImpl { - - CurseOfOblivionAbility() { - super(Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, StaticFilters.FILTER_CARD_CARDS, 2, false)); - } - - private CurseOfOblivionAbility(final CurseOfOblivionAbility ability) { - super(ability); - } - - @Override - public CurseOfOblivionAbility copy() { - return new CurseOfOblivionAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = getSourcePermanentOrLKI(game); - if (enchantment == null || !game.isActivePlayer(enchantment.getAttachedTo())) { - return false; - } - this.getEffects().setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); - return true; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, that player exiles two cards from their graveyard."; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java b/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java index c79b826847f..9803b34953e 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java @@ -1,7 +1,7 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; import mage.abilities.keyword.EnchantAbility; @@ -10,19 +10,11 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -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 mage.players.Player; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** - * * @author Alvin */ public final class CurseOfTheBloodyTome extends CardImpl { @@ -39,8 +31,9 @@ public final class CurseOfTheBloodyTome extends CardImpl { this.addAbility(ability); // At the beginning of enchanted player's upkeep, that player puts the top two cards of their library into their graveyard. - this.addAbility(new CurseOfTheBloodyTomeAbility()); - + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility( + new PutLibraryIntoGraveTargetEffect(2).setText("that player mills two cards") + )); } private CurseOfTheBloodyTome(final CurseOfTheBloodyTome card) { @@ -52,42 +45,3 @@ public final class CurseOfTheBloodyTome extends CardImpl { return new CurseOfTheBloodyTome(this); } } - -class CurseOfTheBloodyTomeAbility extends TriggeredAbilityImpl { - - public CurseOfTheBloodyTomeAbility() { - super(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(2)); - } - - public CurseOfTheBloodyTomeAbility(final CurseOfTheBloodyTomeAbility ability) { - super(ability); - } - - @Override - public CurseOfTheBloodyTomeAbility copy() { - return new CurseOfTheBloodyTomeAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.sourceId); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.isActivePlayer(player.getId())) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, that player mills two cards."; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java b/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java index 615ff1880b8..d12b08f91ae 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java @@ -1,7 +1,7 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; @@ -10,17 +10,15 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterPlaneswalkerPermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -41,7 +39,7 @@ public final class CurseOfThePiercedHeart extends CardImpl { this.addAbility(ability); // At the beginning of enchanted player's upkeep, Curse of the Pierced Heart deals 1 damage to that player. - this.addAbility(new CurseOfThePiercedHeartAbility()); + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility(new CurseOfThePiercedHeartEffect())); } private CurseOfThePiercedHeart(final CurseOfThePiercedHeart card) { @@ -54,55 +52,14 @@ public final class CurseOfThePiercedHeart extends CardImpl { } } -class CurseOfThePiercedHeartAbility extends TriggeredAbilityImpl { - - public CurseOfThePiercedHeartAbility() { - super(Zone.BATTLEFIELD, new CurseOfThePiercedHeartEffect()); - } - - public CurseOfThePiercedHeartAbility(final CurseOfThePiercedHeartAbility ability) { - super(ability); - } - - @Override - public CurseOfThePiercedHeartAbility copy() { - return new CurseOfThePiercedHeartAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.sourceId); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.isActivePlayer(player.getId())) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, " - + "{this} deals 1 damage to that player or a planeswalker that player controls."; - } - -} - class CurseOfThePiercedHeartEffect extends OneShotEffect { - public CurseOfThePiercedHeartEffect() { + CurseOfThePiercedHeartEffect() { super(Outcome.Damage); this.staticText = "{this} deals 1 damage to that player or a planeswalker that player controls"; } - public CurseOfThePiercedHeartEffect(final CurseOfThePiercedHeartEffect effect) { + private CurseOfThePiercedHeartEffect(final CurseOfThePiercedHeartEffect effect) { super(effect); } @@ -114,29 +71,23 @@ class CurseOfThePiercedHeartEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent enchantment = game.getPermanent(source.getSourceId()); - if (controller == null || enchantment == null) { + Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); + if (controller == null || opponent == null) { return false; } - UUID opponentId = enchantment.getAttachedTo(); - Player opponent = game.getPlayer(opponentId); - if (opponent == null) { - return false; + if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_PERMANENT_PLANESWALKER, source.getSourceId(), opponent.getId(), game) < 1 + || !controller.chooseUse(Outcome.Damage, "Redirect to a planeswalker controlled by " + opponent.getLogName() + "?", source, game)) { + return opponent.damage(1, source.getSourceId(), source, game) > 0; } - if (!game.getBattlefield().getAllActivePermanents(new FilterPlaneswalkerPermanent(), opponentId, game).isEmpty()) { - if (controller.chooseUse(Outcome.Damage, "Redirect to a planeswalker controlled by " + opponent.getLogName() + "?", source, game)) { - FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent("a planeswalker controlled by " + opponent.getLogName()); - filter.add(new ControllerIdPredicate(opponentId)); - TargetPermanent target = new TargetPermanent(1, 1, filter, false); - if (target.choose(Outcome.Damage, controller.getId(), source.getSourceId(), game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - return permanent.damage(1, source.getSourceId(), source, game, false, true) > 0; - } - } - } + FilterPermanent filter = new FilterPlaneswalkerPermanent("a planeswalker controlled by " + opponent.getLogName()); + filter.add(new ControllerIdPredicate(opponent.getId())); + TargetPermanent target = new TargetPermanent(filter); + target.setNotTarget(true); + controller.choose(outcome, target, source.getSourceId(), game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + return permanent.damage(1, source.getSourceId(), source, game, false, true) > 0; } - opponent.damage(1, source.getSourceId(), source, game); - return true; + return opponent.damage(1, source.getSourceId(), source, game) > 0; } } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java index d4e436e4309..bffb0a1ea66 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java @@ -1,7 +1,7 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -12,19 +12,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -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 mage.players.Player; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; +import java.util.Objects; import java.util.UUID; /** - * * @author BetaSteward */ public final class CurseOfThirst extends CardImpl { @@ -40,8 +35,10 @@ public final class CurseOfThirst extends CardImpl { this.addAbility(new EnchantAbility(auraTarget.getTargetName())); // At the beginning of enchanted player's upkeep, Curse of Thirst deals damage to that player equal to the number of Curses attached to them. - this.addAbility(new CurseOfThirstAbility()); - + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility( + new DamageTargetEffect(CursesAttachedCount.instance) + .setText("{this} deals damage to that player equal to the number of Curses attached to them") + )); } private CurseOfThirst(final CurseOfThirst card) { @@ -54,73 +51,28 @@ public final class CurseOfThirst extends CardImpl { } } -class CurseOfThirstAbility extends TriggeredAbilityImpl { - - public CurseOfThirstAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(new CursesAttachedCount())); - } - - public CurseOfThirstAbility(final CurseOfThirstAbility ability) { - super(ability); - } - - @Override - public CurseOfThirstAbility copy() { - return new CurseOfThirstAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.sourceId); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.isActivePlayer(player.getId())) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, Curse of Thirst " - + "deals damage to that player equal to the number of Curses attached to them."; - } - -} - -class CursesAttachedCount implements DynamicValue { - - public CursesAttachedCount() { - } +enum CursesAttachedCount implements DynamicValue { + instance; @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { - int count = 0; - Permanent enchantment = game.getPermanent(sourceAbility.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null) { - for (UUID attachmentId : player.getAttachments()) { - Permanent attachment = game.getPermanent(attachmentId); - if (attachment != null && attachment.hasSubtype(SubType.CURSE, game)) { - count++; - } - } - } + Player player = game.getPlayer(effect.getTargetPointer().getFirst(game, sourceAbility)); + if (player == null) { + return 0; } - return count; + return player + .getAttachments() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .map(p -> p.hasSubtype(SubType.CURSE, game)) + .mapToInt(x -> x ? 1 : 0) + .sum(); } @Override - public DynamicValue copy() { - return new CursesAttachedCount(); + public CursesAttachedCount copy() { + return instance; } @Override diff --git a/Mage.Sets/src/mage/cards/i/InfectiousCurse.java b/Mage.Sets/src/mage/cards/i/InfectiousCurse.java index c7efdb6cf95..cc822992d5b 100644 --- a/Mage.Sets/src/mage/cards/i/InfectiousCurse.java +++ b/Mage.Sets/src/mage/cards/i/InfectiousCurse.java @@ -2,7 +2,7 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.SpellAbility; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.GainLifeEffect; @@ -13,12 +13,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.stack.Spell; -import mage.players.Player; import mage.target.TargetPlayer; -import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; import java.util.Objects; @@ -48,9 +45,11 @@ public final class InfectiousCurse extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfectiousCurseCostReductionEffect())); // At the beginning of enchanted player's upkeep, that player loses 1 life and you gain 1 life. - InfectiousCurseAbility curseAbility = new InfectiousCurseAbility(); - curseAbility.addEffect(new GainLifeEffect(1)); - this.addAbility(curseAbility); + Ability ability = new BeginningOfUpkeepAttachedTriggeredAbility( + new LoseLifeTargetEffect(1).setText("that player loses 1 life") + ); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + this.addAbility(ability); } private InfectiousCurse(final InfectiousCurse card) { @@ -63,54 +62,14 @@ public final class InfectiousCurse extends CardImpl { } } -class InfectiousCurseAbility extends TriggeredAbilityImpl { - - public InfectiousCurseAbility() { - super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1)); - } - - public InfectiousCurseAbility(final InfectiousCurseAbility ability) { - super(ability); - } - - @Override - public InfectiousCurseAbility copy() { - return new InfectiousCurseAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.sourceId); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.isActivePlayer(player.getId())) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, that player loses 1 life and you gain 1 life."; - } - -} - class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl { - public InfectiousCurseCostReductionEffect() { + InfectiousCurseCostReductionEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.staticText = "Spells you cast that target enchanted player cost {1} less to cast"; } - protected InfectiousCurseCostReductionEffect(InfectiousCurseCostReductionEffect effect) { + private InfectiousCurseCostReductionEffect(InfectiousCurseCostReductionEffect effect) { super(effect); } diff --git a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java index 8bcbeaf4b77..ac2d734da37 100644 --- a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java +++ b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java @@ -1,8 +1,7 @@ - package mage.cards.t; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepAttachedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; @@ -11,11 +10,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; @@ -25,7 +21,6 @@ import mage.target.TargetPlayer; import java.util.UUID; /** - * * @author LevelX2 */ public final class TormentOfScarabs extends CardImpl { @@ -43,7 +38,7 @@ public final class TormentOfScarabs extends CardImpl { this.addAbility(ability); // At the beginning of enchanted player's upkeep, that player loses 3 life unless they sacrifice a nonland permanent or discards a card. - this.addAbility(new TormentOfScarabsAbility()); + this.addAbility(new BeginningOfUpkeepAttachedTriggeredAbility(new TormentOfScarabsEffect())); } private TormentOfScarabs(final TormentOfScarabs card) { @@ -56,52 +51,14 @@ public final class TormentOfScarabs extends CardImpl { } } -class TormentOfScarabsAbility extends TriggeredAbilityImpl { - - public TormentOfScarabsAbility() { - super(Zone.BATTLEFIELD, new TormentOfScarabsEffect()); - } - - public TormentOfScarabsAbility(final TormentOfScarabsAbility ability) { - super(ability); - } - - @Override - public TormentOfScarabsAbility copy() { - return new TormentOfScarabsAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo() != null) { - if (game.isActivePlayer(enchantment.getAttachedTo())) { - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "At the beginning of enchanted player's upkeep, that player loses 3 life unless they sacrifice a nonland permanent or discards a card."; - } - -} - class TormentOfScarabsEffect extends OneShotEffect { - public TormentOfScarabsEffect() { + TormentOfScarabsEffect() { super(Outcome.LoseLife); - this.staticText = "that player loses 3 life unless they sacrifice a nonland permanent or discards a card"; + this.staticText = "that player loses 3 life unless they sacrifice a nonland permanent or discard a card"; } - public TormentOfScarabsEffect(final TormentOfScarabsEffect effect) { + private TormentOfScarabsEffect(final TormentOfScarabsEffect effect) { super(effect); } @@ -112,33 +69,28 @@ class TormentOfScarabsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent enchantment = game.getPermanent(source.getSourceId()); - if (enchantment == null || enchantment.getAttachedTo() == null) { + Player enchantedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (enchantedPlayer == null) { return false; } - Player enchantedPlayer = game.getPlayer(enchantment.getAttachedTo()); - if (enchantedPlayer != null) { - int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, enchantedPlayer.getId(), game); - if (permanents > 0 && enchantedPlayer.chooseUse(outcome, "Sacrifice a nonland permanent?", - "Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) { - Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); - if (enchantedPlayer.choose(outcome, target, source.getSourceId(), game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - permanent.sacrifice(source, game); - return true; - } + int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, enchantedPlayer.getId(), game); + if (permanents > 0 && enchantedPlayer.chooseUse(outcome, "Sacrifice a nonland permanent?", + "Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) { + Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); + if (enchantedPlayer.choose(outcome, target, source.getSourceId(), game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source, game); + return true; } } - if (!enchantedPlayer.getHand().isEmpty() && enchantedPlayer.chooseUse(outcome, "Discard a card?", - "Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) { - enchantedPlayer.discardOne(false, false, source, game); - return true; - } - enchantedPlayer.loseLife(3, game, source, false); + } + if (!enchantedPlayer.getHand().isEmpty() && enchantedPlayer.chooseUse(outcome, "Discard a card?", + "Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) { + enchantedPlayer.discardOne(false, false, source, game); return true; } - - return false; + enchantedPlayer.loseLife(3, game, source, false); + return true; } } diff --git a/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepAttachedTriggeredAbility.java new file mode 100644 index 00000000000..27d0c126212 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepAttachedTriggeredAbility.java @@ -0,0 +1,52 @@ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * @author TheElk801 + */ +public class BeginningOfUpkeepAttachedTriggeredAbility extends TriggeredAbilityImpl { + + public BeginningOfUpkeepAttachedTriggeredAbility(Effect effect) { + this(effect, false); + } + + public BeginningOfUpkeepAttachedTriggeredAbility(Effect effect, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + } + + private BeginningOfUpkeepAttachedTriggeredAbility(final BeginningOfUpkeepAttachedTriggeredAbility ability) { + super(ability); + } + + @Override + public BeginningOfUpkeepAttachedTriggeredAbility copy() { + return new BeginningOfUpkeepAttachedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent enchantment = getSourcePermanentOrLKI(game); + if (enchantment == null || !game.isActivePlayer(enchantment.getAttachedTo())) { + return false; + } + this.getEffects().setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); + return true; + } + + @Override + public String getRule() { + return "At the beginning of enchanted player's upkeep, " + super.getRule(); + } +}