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 0000000000..a3aed39c2b --- /dev/null +++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java @@ -0,0 +1,142 @@ +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.RestrictionEffect; +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. + 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 = 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; + } +} + +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; + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2018.java b/Mage.Sets/src/mage/sets/Commander2018.java index 285dbbf909..7a6da2d294 100644 --- a/Mage.Sets/src/mage/sets/Commander2018.java +++ b/Mage.Sets/src/mage/sets/Commander2018.java @@ -319,6 +319,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 0000000000..5d6ecf576b --- /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