From bd76e54e9d3989e522630dd97456f111ed196cc6 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 10 Jan 2020 14:18:56 +0100 Subject: [PATCH] * Xantcha, Sleeper Agent - Fixed wording of the replacement effect (Oracle changes from 2019-09-27) and generalized the effect for 3 cards. --- .../src/mage/cards/c/CaptiveAudience.java | 51 +------------ .../src/mage/cards/p/PendantOfProsperity.java | 46 +----------- .../src/mage/cards/x/XantchaSleeperAgent.java | 64 +++-------------- ...dUnderControlOfOpponentOfChoiceEffect.java | 72 +++++++++++++++++++ 4 files changed, 86 insertions(+), 147 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldUnderControlOfOpponentOfChoiceEffect.java diff --git a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java index 342849027dc..8481ae82a48 100644 --- a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java +++ b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java @@ -4,27 +4,22 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenTargetEffect; import mage.abilities.effects.common.SetPlayerLifeSourceEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.TargetController; import mage.game.Game; import mage.game.permanent.token.ZombieToken; import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import java.util.UUID; +import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; import static mage.constants.Outcome.Benefit; @@ -37,7 +32,7 @@ public final class CaptiveAudience extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{B}{R}"); // Captive Audience enters the battlefield under the control of an opponent of your choice. - this.addAbility(new EntersBattlefieldAbility(new CaptiveAudienceETBEffect())); + this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect())); // At the beginning of your upkeep, choose one that hasn't been chosen — // • Your life total becomes 4. @@ -64,48 +59,6 @@ public final class CaptiveAudience extends CardImpl { } } -class CaptiveAudienceETBEffect extends OneShotEffect { - - CaptiveAudienceETBEffect() { - super(Benefit); - staticText = "under the control of an opponent of your choice"; - } - - private CaptiveAudienceETBEffect(final CaptiveAudienceETBEffect effect) { - super(effect); - } - - @Override - public CaptiveAudienceETBEffect copy() { - return new CaptiveAudienceETBEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Target target = new TargetOpponent(); - target.setNotTarget(true); - if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - return false; - } - Player player = game.getPlayer(target.getFirstTarget()); - if (player == null) { - return false; - } - ContinuousEffect continuousEffect = new GainControlTargetEffect( - Duration.WhileOnBattlefield, true, player.getId() - ); - continuousEffect.setTargetPointer(new FixedTarget( - source.getSourceId(), source.getSourceObjectZoneChangeCounter() - )); - game.addEffect(continuousEffect, source); - return true; - } -} - class CaptiveAudienceCreateTokensEffect extends OneShotEffect { CaptiveAudienceCreateTokensEffect() { diff --git a/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java b/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java index 2404fa39ee9..bdd8d5f4a16 100644 --- a/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java +++ b/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java @@ -26,6 +26,7 @@ import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import java.util.UUID; +import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; import static mage.constants.Outcome.Benefit; @@ -38,7 +39,7 @@ public final class PendantOfProsperity extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Pendant of Prosperity enters the battlefield under the control of an opponent of your choice. - this.addAbility(new EntersBattlefieldAbility(new PendantOfProsperityETBEffect())); + this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect())); // {2}, {T}: Draw a card, then you may put a land card from your hand onto the battlefield. Pendant of Prosperity's owner draws a card, then that player may put a land card from their hand onto the battlefield. Ability ability = new SimpleActivatedAbility(new PendantOfProsperityEffect(), new GenericManaCost(2)); @@ -56,49 +57,6 @@ public final class PendantOfProsperity extends CardImpl { } } -class PendantOfProsperityETBEffect extends OneShotEffect { - - PendantOfProsperityETBEffect() { - super(Benefit); - staticText = "under the control of an opponent of your choice"; - } - - private PendantOfProsperityETBEffect(final PendantOfProsperityETBEffect effect) { - super(effect); - } - - @Override - public PendantOfProsperityETBEffect copy() { - return new PendantOfProsperityETBEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Target target = new TargetOpponent(); - target.setNotTarget(true); - if (!controller.choose(Benefit, target, source.getSourceId(), game)) { - return false; - } - Player player = game.getPlayer(target.getFirstTarget()); - if (player == null) { - return false; - } - ContinuousEffect continuousEffect = new GainControlTargetEffect( - Duration.WhileOnBattlefield, true, player.getId() - ); - continuousEffect.setTargetPointer(new FixedTarget( - source.getSourceId(), source.getSourceObjectZoneChangeCounter() - )); - game.addEffect(continuousEffect, source); - return true; - } - -} - class PendantOfProsperityEffect extends OneShotEffect { private static final Effect effect1 = new DrawCardSourceControllerEffect(1); diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java index ac57b4a83be..41800ad8537 100644 --- a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java +++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java @@ -2,31 +2,24 @@ package mage.cards.x; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AttacksEachCombatStaticAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.LoseLifePermanentControllerEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetOpponent; -import mage.target.targetpointer.FixedTarget; import java.util.Objects; import java.util.UUID; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; -import static mage.constants.Outcome.Benefit; /** * @author jesusjbr @@ -41,9 +34,14 @@ public final class XantchaSleeperAgent extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(5); - // As Xantcha, Sleeper Agent enters the battlefield, an opponent of your choice gains control of it. - this.addAbility(new AsEntersBattlefieldAbility(new XantchaSleeperAgentChangeControlEffect())); - + // Xantcha, Sleeper Agent enters the battlefield under the control of an opponent of your choice. + /** + * Xantcha’s first ability is a replacement effect that modifies how it enters the battlefield, + * not a triggered ability. Players can’t take actions (such as activating its last ability) + * while Xantcha’s on the battlefield before it’s controlled by another player. (2018-07-13) + * */ + this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect())); + // Xantcha attacks each combat if able and can’t attack its owner or planeswalkers its owner controls. Ability ability = new AttacksEachCombatStaticAbility(); ability.addEffect(new XantchaSleeperAgentAttackRestrictionEffect()); @@ -71,48 +69,6 @@ public final class XantchaSleeperAgent extends CardImpl { } } -class XantchaSleeperAgentChangeControlEffect extends OneShotEffect { - - XantchaSleeperAgentChangeControlEffect() { - super(Benefit); - staticText = "an opponent of your choice gains control of it."; - } - - private XantchaSleeperAgentChangeControlEffect(final XantchaSleeperAgentChangeControlEffect effect) { - super(effect); - } - - @Override - public XantchaSleeperAgentChangeControlEffect copy() { - return new XantchaSleeperAgentChangeControlEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Target target = new TargetOpponent(); - target.setNotTarget(true); - if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - return false; - } - Player player = game.getPlayer(target.getFirstTarget()); - if (player == null) { - return false; - } - ContinuousEffect continuousEffect = new GainControlTargetEffect( - Duration.WhileOnBattlefield, true, player.getId() - ); - continuousEffect.setTargetPointer(new FixedTarget( - source.getSourceId(), source.getSourceObjectZoneChangeCounter() - )); - game.addEffect(continuousEffect, source); - return true; - } -} - class XantchaSleeperAgentAttackRestrictionEffect extends RestrictionEffect { XantchaSleeperAgentAttackRestrictionEffect() { diff --git a/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldUnderControlOfOpponentOfChoiceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldUnderControlOfOpponentOfChoiceEffect.java new file mode 100644 index 00000000000..2d3a8c5639c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldUnderControlOfOpponentOfChoiceEffect.java @@ -0,0 +1,72 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import static mage.constants.Outcome.Benefit; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * Use this effect only with EntersBattlefieldAbility like abilities + * + * @author LevelX2 + */ + +public class EntersBattlefieldUnderControlOfOpponentOfChoiceEffect extends OneShotEffect { + + public EntersBattlefieldUnderControlOfOpponentOfChoiceEffect() { + super(Benefit); + staticText = "under the control of an opponent of your choice"; + } + + private EntersBattlefieldUnderControlOfOpponentOfChoiceEffect(final EntersBattlefieldUnderControlOfOpponentOfChoiceEffect effect) { + super(effect); + } + + @Override + public EntersBattlefieldUnderControlOfOpponentOfChoiceEffect copy() { + return new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Target target = new TargetOpponent(); + target.setNotTarget(true); + if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + return false; + } + Player opponent = game.getPlayer(target.getFirstTarget()); + if (opponent == null) { + return false; + } + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent != null) { + game.informPlayers(permanent.getLogName() + " enters the battlefield under the control of " + opponent.getLogName()); + } + ContinuousEffect continuousEffect = new GainControlTargetEffect( + Duration.Custom, true, opponent.getId() + ); + continuousEffect.setTargetPointer(new FixedTarget( + source.getSourceId(), source.getSourceObjectZoneChangeCounter() + )); + game.addEffect(continuousEffect, source); + return true; + } +} \ No newline at end of file