fixed Not of this World not working with modal spells

This commit is contained in:
Evan Kranzler 2019-08-19 21:40:37 -04:00
parent e631a25b9b
commit 35b1233a2b

View file

@ -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<UUID> possibleTargets(UUID sourceControllerId, Game game) {
Set<UUID> 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