From 35b1233a2b24eba79d2da278b5da377df58f7088 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 19 Aug 2019 21:40:37 -0400 Subject: [PATCH] fixed Not of this World not working with modal spells --- .../src/mage/cards/n/NotOfThisWorld.java | 129 +++++++++--------- 1 file changed, 68 insertions(+), 61 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java index 740bd42953c..b3d50c71da4 100644 --- a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java +++ b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java @@ -1,33 +1,30 @@ - package mage.cards.n; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.Modes; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.ComparisonType; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.Filter; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.game.stack.StackAbility; import mage.game.stack.StackObject; import mage.target.Target; import mage.target.TargetObject; -import mage.target.Targets; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** * @author Rafbill @@ -39,14 +36,14 @@ public final class NotOfThisWorld extends CardImpl { this.subtype.add(SubType.ELDRAZI); // Counter target spell or ability that targets a permanent you control. - this.getSpellAbility().addTarget( - new TargetStackObjectTargetingControlledPermanent()); + this.getSpellAbility().addTarget(new TargetStackObjectTargetingControlledPermanent()); this.getSpellAbility().addEffect(new CounterTargetEffect()); + // Not of This World costs {7} less to cast if it targets a spell or ability that targets a creature you control with power 7 or greater. this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(7, NotOfThisWorldCondition.instance))); } - public NotOfThisWorld(final NotOfThisWorld card) { + private NotOfThisWorld(final NotOfThisWorld card) { super(card); } @@ -58,14 +55,14 @@ public final class NotOfThisWorld extends CardImpl { class TargetStackObjectTargetingControlledPermanent extends TargetObject { - public TargetStackObjectTargetingControlledPermanent() { + TargetStackObjectTargetingControlledPermanent() { this.minNumberOfTargets = 1; this.maxNumberOfTargets = 1; this.zone = Zone.STACK; this.targetName = "spell or ability that targets a permanent you control"; } - public TargetStackObjectTargetingControlledPermanent(final TargetStackObjectTargetingControlledPermanent target) { + private TargetStackObjectTargetingControlledPermanent(final TargetStackObjectTargetingControlledPermanent target) { super(target); } @@ -87,22 +84,20 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject { @Override public boolean canChoose(UUID sourceControllerId, Game game) { - for (StackObject stackObject : game.getStack()) { - if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { - Targets objectTargets = stackObject.getStackAbility().getTargets(); - if (!objectTargets.isEmpty()) { - for (Target target : objectTargets) { - for (UUID targetId : target.getTargets()) { - Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); - if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) { - return true; - } - } - } - } - } - } - return false; + return game.getStack() + .stream() + .filter(stackObject -> stackObject instanceof Spell || stackObject instanceof StackAbility) + .map(StackObject::getStackAbility) + .map(Ability::getModes) + .map(Modes::values) + .flatMap(Collection::stream) + .map(Mode::getTargets) + .flatMap(Collection::stream) + .filter(target -> !target.isNotTarget()) + .map(Target::getTargets) + .flatMap(Collection::stream) + .map(game::getPermanentOrLKIBattlefield) + .anyMatch(permanent -> permanent != null && permanent.isControlledBy(sourceControllerId)); } @Override @@ -114,21 +109,26 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject { @Override public Set possibleTargets(UUID sourceControllerId, Game game) { Set possibleTargets = new HashSet<>(); - for (StackObject stackObject : game.getStack()) { - if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { - Targets objectTargets = stackObject.getStackAbility().getTargets(); - if (!objectTargets.isEmpty()) { - for (Target target : objectTargets) { - for (UUID targetId : target.getTargets()) { - Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); - if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) { - possibleTargets.add(stackObject.getId()); - } - } - } - } + game.getStack().stream().forEach(stackObject -> { + if (!(stackObject instanceof Spell || stackObject instanceof StackAbility)) { + return; } - } + boolean flag = stackObject + .getStackAbility() + .getModes() + .values() + .stream() + .map(Mode::getTargets) + .flatMap(Collection::stream) + .filter(target -> !target.isNotTarget()) + .map(Target::getTargets) + .flatMap(Collection::stream) + .map(game::getPermanentOrLKIBattlefield) + .anyMatch(permanent -> permanent != null && permanent.isControlledBy(sourceControllerId)); + if (flag) { + possibleTargets.add(stackObject.getId()); + } + }); return possibleTargets; } @@ -140,8 +140,9 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject { } enum NotOfThisWorldCondition implements Condition { + instance; - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control with power 7 or greater"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); static { filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 6)); @@ -149,24 +150,30 @@ enum NotOfThisWorldCondition implements Condition { } - @Override public boolean apply(Game game, Ability source) { StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId()); - if (sourceSpell != null && sourceSpell.getStackAbility().getTargets().isChosen()) { - StackObject objectToCounter = game.getStack().getStackObject(sourceSpell.getStackAbility().getTargets().getFirstTarget()); - if (objectToCounter != null) { - for (Target target : objectToCounter.getStackAbility().getTargets()) { - for (UUID targetId : target.getTargets()) { - Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); - if (targetedPermanent != null && filter.match(targetedPermanent, sourceSpell.getSourceId(), sourceSpell.getControllerId(), game)) { - return true; - } - } - } - } + if (sourceSpell == null || !sourceSpell.getStackAbility().getTargets().isChosen()) { + return false; } - return false; + StackObject objectToCounter = game.getStack().getStackObject(sourceSpell.getStackAbility().getTargets().getFirstTarget()); + if (objectToCounter == null) { + return false; + } + return objectToCounter + .getStackAbility() + .getModes() + .values() + .stream() + .map(Mode::getTargets) + .flatMap(Collection::stream) + .filter(target -> !target.isNotTarget()) + .map(Target::getTargets) + .flatMap(Collection::stream) + .map(game::getPermanentOrLKIBattlefield) + .anyMatch(permanent -> permanent != null && filter.match( + permanent, sourceSpell.getSourceId(), sourceSpell.getControllerId(), game + )); } @Override