diff --git a/Mage.Sets/src/mage/cards/b/BarrinsSpite.java b/Mage.Sets/src/mage/cards/b/BarrinsSpite.java index f90e68333c5..2763a578544 100644 --- a/Mage.Sets/src/mage/cards/b/BarrinsSpite.java +++ b/Mage.Sets/src/mage/cards/b/BarrinsSpite.java @@ -7,11 +7,12 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; -import mage.target.common.TargetCreaturePermanentSameController; +import mage.target.common.TargetPermanentSameController; import java.util.Collection; import java.util.List; @@ -29,7 +30,7 @@ public final class BarrinsSpite extends CardImpl { // Choose two target creatures controlled by the same player. Their controller chooses and sacrifices one of them. Return the other to its owner's hand. this.getSpellAbility().addEffect(new BarrinsSpiteEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2)); + this.getSpellAbility().addTarget(new TargetPermanentSameController(StaticFilters.FILTER_PERMANENT_CREATURES)); } private BarrinsSpite(final BarrinsSpite card) { diff --git a/Mage.Sets/src/mage/cards/c/Cannibalize.java b/Mage.Sets/src/mage/cards/c/Cannibalize.java index 9ddb072a474..13c4c4a69ad 100644 --- a/Mage.Sets/src/mage/cards/c/Cannibalize.java +++ b/Mage.Sets/src/mage/cards/c/Cannibalize.java @@ -8,10 +8,11 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCreaturePermanentSameController; +import mage.target.common.TargetPermanentSameController; import java.util.List; import java.util.Objects; @@ -28,7 +29,7 @@ public final class Cannibalize extends CardImpl { // Choose two target creatures controlled by the same player. Exile one of the creatures and put two +1/+1 counters on the other. this.getSpellAbility().addEffect(new CannibalizeEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2)); + this.getSpellAbility().addTarget(new TargetPermanentSameController(StaticFilters.FILTER_PERMANENT_CREATURES)); } private Cannibalize(final Cannibalize card) { diff --git a/Mage.Sets/src/mage/cards/i/Incriminate.java b/Mage.Sets/src/mage/cards/i/Incriminate.java index ef257e29f49..32eb1daa2b7 100644 --- a/Mage.Sets/src/mage/cards/i/Incriminate.java +++ b/Mage.Sets/src/mage/cards/i/Incriminate.java @@ -1,25 +1,25 @@ package mage.cards.i; -import java.util.ArrayList; -import java.util.List; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCreaturePermanentSameController; - -import java.util.UUID; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.PermanentIdPredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetPermanentSameController; import mage.target.common.TargetSacrifice; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * @author TheElk801 */ @@ -30,7 +30,7 @@ public final class Incriminate extends CardImpl { // Choose two target creatures controlled by the same player. That player sacrifices one of them. this.getSpellAbility().addEffect(new IncriminateEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2)); + this.getSpellAbility().addTarget(new TargetPermanentSameController(StaticFilters.FILTER_PERMANENT_CREATURES)); } private Incriminate(final Incriminate card) { diff --git a/Mage.Sets/src/mage/cards/s/SorrowsPath.java b/Mage.Sets/src/mage/cards/s/SorrowsPath.java index 19836342a1f..6bdf665be60 100644 --- a/Mage.Sets/src/mage/cards/s/SorrowsPath.java +++ b/Mage.Sets/src/mage/cards/s/SorrowsPath.java @@ -21,7 +21,7 @@ import mage.game.events.BlockerDeclaredEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCreaturePermanentSameController; +import mage.target.common.TargetPermanentSameController; import java.util.HashSet; import java.util.List; @@ -44,7 +44,7 @@ public final class SorrowsPath extends CardImpl { // {T}: Choose two target blocking creatures an opponent controls. If each of those creatures could block all creatures that the other is blocking, remove both of them from combat. Each one then blocks all creatures the other was blocking. Ability ability = new SimpleActivatedAbility(new SorrowsPathSwitchBlockersEffect(), new TapSourceCost()); - ability.addTarget(new TargetCreaturePermanentSameController(2, filter)); + ability.addTarget(new TargetPermanentSameController(filter)); this.addAbility(ability); // Whenever Sorrow's Path becomes tapped, it deals 2 damage to you and each creature you control. diff --git a/Mage.Sets/src/mage/cards/t/TheAnimus.java b/Mage.Sets/src/mage/cards/t/TheAnimus.java index 8d4fa1db8ef..74524f64cf4 100644 --- a/Mage.Sets/src/mage/cards/t/TheAnimus.java +++ b/Mage.Sets/src/mage/cards/t/TheAnimus.java @@ -1,15 +1,15 @@ package mage.cards.t; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; -import mage.cards.*; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterCard; @@ -18,11 +18,14 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.TargetPermanent; import mage.target.Targets; -import mage.target.common.*; +import mage.target.common.TargetCardInExile; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; /** - * * @author grimreap124 */ public final class TheAnimus extends CardImpl { @@ -37,7 +40,7 @@ public final class TheAnimus extends CardImpl { public TheAnimus(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - + this.supertype.add(SuperType.LEGENDARY); // At the beginning of your end step, exile up to one target legendary creature card from a graveyard with a memory counter on it. @@ -47,7 +50,7 @@ public final class TheAnimus extends CardImpl { // {T}: Until your next turn, target legendary creature you control becomes a copy of target creature card in exile with a memory counter on it. Activate only as a sorcery. ability = new ActivateAsSorceryActivatedAbility(new TheAnimusCopyEffect(), new TapSourceCost()); - ability.addTarget(new TargetCreaturePermanentSameController(1, StaticFilters.FILTER_CREATURE_LEGENDARY)); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY)); ability.addTarget(new TargetCardInExile(1, 1, exileFilter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TrialOfAgony.java b/Mage.Sets/src/mage/cards/t/TrialOfAgony.java new file mode 100644 index 00000000000..3b4f84a100d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrialOfAgony.java @@ -0,0 +1,120 @@ +package mage.cards.t; + +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetPermanentSameController; +import mage.target.targetpointer.FixedTarget; +import mage.util.RandomUtil; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class TrialOfAgony extends CardImpl { + + public TrialOfAgony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); + + // Choose two target creatures controlled by the same opponent. That player chooses one of those creatures. Trial of Agony deals 5 damage to that creature, and the other can't block this turn. + this.getSpellAbility().addEffect(new TrialOfAgonyEffect()); + this.getSpellAbility().addTarget(new TargetPermanentSameController(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES)); + } + + private TrialOfAgony(final TrialOfAgony card) { + super(card); + } + + @Override + public TrialOfAgony copy() { + return new TrialOfAgony(this); + } +} + +class TrialOfAgonyEffect extends OneShotEffect { + + TrialOfAgonyEffect() { + super(Outcome.Benefit); + staticText = "choose two target creatures controlled by the same opponent. " + + "That player chooses one of those creatures. " + + "{this} deals 5 damage to that creature, and the other can't block this turn"; + } + + private TrialOfAgonyEffect(final TrialOfAgonyEffect effect) { + super(effect); + } + + @Override + public TrialOfAgonyEffect copy() { + return new TrialOfAgonyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = this + .getTargetPointer() + .getTargets(game, source) + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + Permanent toDamage; + Permanent cantBlock; + switch (permanents.size()) { + case 0: + return false; + case 1: + toDamage = permanents.get(0); + cantBlock = null; + break; + default: + Player player = game.getPlayer(permanents.get(0).getControllerId()); + if (player == null) { + toDamage = permanents.get(0); + cantBlock = permanents.get(1); + break; + } + FilterPermanent filter = new FilterPermanent(); + filter.add(Predicates.or( + permanents + .stream() + .map(MageItem::getId) + .map(ControllerIdPredicate::new) + .collect(Collectors.toList()) + )); + TargetPermanent target = new TargetPermanent(filter); + target.withChooseHint("to deal damage to"); + target.withNotTarget(true); + player.choose(outcome, target, source, game); + toDamage = game.getPermanent(target.getFirstTarget()); + permanents.remove(toDamage); + cantBlock = RandomUtil.randomFromCollection(permanents); + } + if (toDamage != null) { + toDamage.damage(5, source, game); + } + if (cantBlock != null) { + game.addEffect(new CantBlockTargetEffect(Duration.EndOfTurn) + .setTargetPointer(new FixedTarget(cantBlock, game)), source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java index de5f9106a60..168c166d827 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java @@ -379,7 +379,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Toby, Beastie Befriender", 35, Rarity.RARE, mage.cards.t.TobyBeastieBefriender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toby, Beastie Befriender", 356, Rarity.RARE, mage.cards.t.TobyBeastieBefriender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Trapped in the Screen", 36, Rarity.COMMON, mage.cards.t.TrappedInTheScreen.class)); - //cards.add(new SetCardInfo("Trial of Agony", 159, Rarity.UNCOMMON, mage.cards.t.TrialOfAgony.class)); + cards.add(new SetCardInfo("Trial of Agony", 159, Rarity.UNCOMMON, mage.cards.t.TrialOfAgony.class)); cards.add(new SetCardInfo("Tunnel Surveyor", 76, Rarity.COMMON, mage.cards.t.TunnelSurveyor.class)); cards.add(new SetCardInfo("Turn Inside Out", 160, Rarity.COMMON, mage.cards.t.TurnInsideOut.class)); cards.add(new SetCardInfo("Twist Reality", 77, Rarity.COMMON, mage.cards.t.TwistReality.class)); diff --git a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java b/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java deleted file mode 100644 index d0ea77eb906..00000000000 --- a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.target.common; - -import mage.abilities.Ability; -import mage.filter.StaticFilters; -import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public class TargetCreaturePermanentSameController extends TargetCreaturePermanent { - - public TargetCreaturePermanentSameController(int numTargets) { - this(numTargets, StaticFilters.FILTER_PERMANENT_CREATURE); - } - - public TargetCreaturePermanentSameController(int numTargets, FilterCreaturePermanent filter) { - super(numTargets, numTargets, filter, false); - } - - protected TargetCreaturePermanentSameController(final TargetCreaturePermanentSameController target) { - super(target); - } - - @Override - public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { - if (super.canTarget(controllerId, id, source, game)) { - Permanent firstTargetPermanent = game.getPermanent(id); - if (firstTargetPermanent != null) { - for (Object object : getTargets()) { - UUID targetId = (UUID) object; - Permanent targetPermanent = game.getPermanent(targetId); - if (targetPermanent != null) { - if (!firstTargetPermanent.getId().equals(targetPermanent.getId())) { - if (!firstTargetPermanent.isControlledBy(targetPermanent.getOwnerId())) { - return false; - } - } - } - } - return true; - } - } - return false; - } - - @Override - public TargetCreaturePermanentSameController copy() { - return new TargetCreaturePermanentSameController(this); - } -} diff --git a/Mage/src/main/java/mage/target/common/TargetPermanentSameController.java b/Mage/src/main/java/mage/target/common/TargetPermanentSameController.java new file mode 100644 index 00000000000..9dd16fff7e8 --- /dev/null +++ b/Mage/src/main/java/mage/target/common/TargetPermanentSameController.java @@ -0,0 +1,54 @@ +package mage.target.common; + +import mage.abilities.Ability; +import mage.filter.FilterPermanent; +import mage.game.Controllable; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; + +import java.util.Objects; +import java.util.UUID; + +/** + * @author LevelX2 + */ +public class TargetPermanentSameController extends TargetPermanent { + + public TargetPermanentSameController(FilterPermanent filter) { + this(2, filter); + } + + public TargetPermanentSameController(int numTargets, FilterPermanent filter) { + super(numTargets, numTargets, filter, false); + } + + protected TargetPermanentSameController(final TargetPermanentSameController target) { + super(target); + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (!super.canTarget(controllerId, id, source, game)) { + return false; + } + if (this.getTargets().isEmpty()) { + return true; + } + Permanent firstTargetPermanent = game.getPermanent(id); + return firstTargetPermanent != null + && this + .getTargets() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .filter(permanent -> !permanent.equals(firstTargetPermanent)) + .map(Controllable::getControllerId) + .allMatch(firstTargetPermanent::isControlledBy); + } + + @Override + public TargetPermanentSameController copy() { + return new TargetPermanentSameController(this); + } +}