From f4515efe41a3ac83440296b9a741e8e3d3f43309 Mon Sep 17 00:00:00 2001 From: jesusjbr Date: Thu, 2 Aug 2018 14:03:33 +0200 Subject: [PATCH 1/2] Xantcha, Sleeper Agent implemented. Added a new effect (LoseLifePermanentControllerEffect). --- .../src/mage/cards/x/XantchaSleeperAgent.java | 98 +++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2018.java | 1 + .../LoseLifePermanentControllerEffect.java | 63 ++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/LoseLifePermanentControllerEffect.java diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java new file mode 100644 index 00000000000..095cf0ec00d --- /dev/null +++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java @@ -0,0 +1,98 @@ +package mage.cards.x; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.*; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.LoseLifePermanentControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetOpponent; + + + +/** + * + * @author jesusjbr + */ + +public final class XantchaSleeperAgent extends CardImpl { + + + + public XantchaSleeperAgent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.MINION); + 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. + Ability ability = new EntersBattlefieldTriggeredAbility(new XantchaSleeperAgentChangeControlEffect()) ; + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + + // Xantcha attacks each combat if able and can’t attack its owner or planeswalkers its owner controls. + this.addAbility(new AttacksEachCombatStaticAbility()); + + // {3}: Xantcha’s controller loses 2 life and you draw a card. Any player may activate this ability. + Effect effect = new LoseLifePermanentControllerEffect(2); + effect.setText("Xantcha’s controller loses 2 life"); + SimpleActivatedAbility simpleAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}")); + + simpleAbility.addEffect(new DrawCardSourceControllerEffect(1).setText("and you draw a card")); + simpleAbility.addEffect(new InfoEffect("Any player may activate this ability")); + simpleAbility.setMayActivate(TargetController.ANY); + this.addAbility(simpleAbility); + + + } + + public XantchaSleeperAgent(final XantchaSleeperAgent card) { + super(card); + } + + @Override + public XantchaSleeperAgent copy() { + return new XantchaSleeperAgent(this); + } +} + + + +class XantchaSleeperAgentChangeControlEffect extends ContinuousEffectImpl { + + public XantchaSleeperAgentChangeControlEffect() { + super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + staticText = "an opponent of your choice gains control of it"; + } + + public XantchaSleeperAgentChangeControlEffect(final XantchaSleeperAgentChangeControlEffect effect) { + super(effect); + } + + @Override + public XantchaSleeperAgentChangeControlEffect copy() { + return new XantchaSleeperAgentChangeControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game); + if (permanent != null) { + return permanent.changeControllerId(source.getFirstTarget(), game); + } else { + discard(); + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Commander2018.java b/Mage.Sets/src/mage/sets/Commander2018.java index 7f1aeea8b0b..32d2806fe65 100644 --- a/Mage.Sets/src/mage/sets/Commander2018.java +++ b/Mage.Sets/src/mage/sets/Commander2018.java @@ -318,6 +318,7 @@ public final class Commander2018 extends ExpansionSet { cards.add(new SetCardInfo("Woodland Stream", 292, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); cards.add(new SetCardInfo("Worm Harvest", 194, Rarity.RARE, mage.cards.w.WormHarvest.class)); cards.add(new SetCardInfo("Worn Powerstone", 230, Rarity.UNCOMMON, mage.cards.w.WornPowerstone.class)); + cards.add(new SetCardInfo("Xantcha, Sleeper Agent", 50, Rarity.RARE, mage.cards.x.XantchaSleeperAgent.class)); cards.add(new SetCardInfo("Yavimaya Elder", 166, Rarity.COMMON, mage.cards.y.YavimayaElder.class)); cards.add(new SetCardInfo("Yavimaya Enchantress", 167, Rarity.COMMON, mage.cards.y.YavimayaEnchantress.class)); cards.add(new SetCardInfo("Yennet, Crypt Sovereign", 51, Rarity.MYTHIC, mage.cards.y.YennetCryptSovereign.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/LoseLifePermanentControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LoseLifePermanentControllerEffect.java new file mode 100644 index 00000000000..5d6ecf576b7 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/LoseLifePermanentControllerEffect.java @@ -0,0 +1,63 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + + + +/** + * This effect applies to the permanent's controller which originated the ability, but not to the controller of that + * source ability. + * @author jesusjbr + */ +public class LoseLifePermanentControllerEffect extends OneShotEffect { + + protected DynamicValue amount; + + public LoseLifePermanentControllerEffect(int amount) { + this(new StaticValue(amount)); + } + + public LoseLifePermanentControllerEffect(DynamicValue amount) { + super(Outcome.LoseLife); + this.amount = amount; + setText(); + } + + public LoseLifePermanentControllerEffect(final LoseLifePermanentControllerEffect effect) { + super(effect); + this.amount = effect.amount.copy(); + } + + @Override + public LoseLifePermanentControllerEffect copy() { + return new LoseLifePermanentControllerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + Player player = null; + if (permanent != null) { + player = game.getPlayer(permanent.getControllerId()); + } + if (player != null) { + player.loseLife(amount.calculate(game, source, this), game, false); + return true; + } + return false; + } + + private void setText() { + StringBuilder sb = new StringBuilder(); + sb.append("controller ").append("loses").append(amount.toString()).append("life"); + staticText += sb.toString(); + } + +} \ No newline at end of file From 8c8a73c791f5bd7f7a0b8b8787a94ad7ea7798de Mon Sep 17 00:00:00 2001 From: jesusjbr Date: Thu, 2 Aug 2018 23:14:23 +0200 Subject: [PATCH 2/2] Added effect to Xantcha, Sleeper Agent. Now this creature can't attack its owner or planeswalkers its owner controls. --- .../src/mage/cards/x/XantchaSleeperAgent.java | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java index 095cf0ec00d..a3aed39c2b4 100644 --- a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java +++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java @@ -7,6 +7,7 @@ import mage.abilities.common.*; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; +import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.LoseLifePermanentControllerEffect; @@ -42,10 +43,13 @@ public final class XantchaSleeperAgent extends CardImpl { this.addAbility(ability); // Xantcha attacks each combat if able and can’t attack its owner or planeswalkers its owner controls. - this.addAbility(new AttacksEachCombatStaticAbility()); + ability = new AttacksEachCombatStaticAbility(); + Effect effect = new XantchaSleeperAgentAttackRestrictionEffect(); + ability.addEffect(effect); + this.addAbility(ability); // {3}: Xantcha’s controller loses 2 life and you draw a card. Any player may activate this ability. - Effect effect = new LoseLifePermanentControllerEffect(2); + effect = new LoseLifePermanentControllerEffect(2); effect.setText("Xantcha’s controller loses 2 life"); SimpleActivatedAbility simpleAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}")); @@ -95,4 +99,44 @@ class XantchaSleeperAgentChangeControlEffect extends ContinuousEffectImpl { } return false; } -} \ No newline at end of file +} + +class XantchaSleeperAgentAttackRestrictionEffect extends RestrictionEffect { + + XantchaSleeperAgentAttackRestrictionEffect() { + super(Duration.WhileOnBattlefield); + staticText = "and can't attack its owner or planeswalkers its owner controls."; + } + + XantchaSleeperAgentAttackRestrictionEffect(final XantchaSleeperAgentAttackRestrictionEffect effect) { + super(effect); + } + + @Override + public XantchaSleeperAgentAttackRestrictionEffect copy() { + return new XantchaSleeperAgentAttackRestrictionEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return true; + } + + @Override + public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) { + + boolean allowAttack = true; + UUID ownerPlayerId = source.getSourcePermanentIfItStillExists(game).getOwnerId(); + + if (defenderId.equals(ownerPlayerId)) { + allowAttack = false; + } + else { + Permanent planeswalker = game.getPermanent(defenderId); + if (planeswalker != null && planeswalker.isControlledBy(ownerPlayerId)) { + allowAttack = false; + } + } + return allowAttack; + } +}