[KHM] fixed Orvar, the All-Form triggered ability not working correctly

This commit is contained in:
Evan Kranzler 2021-02-05 11:33:42 -05:00
parent 25f929d70e
commit ece9108695
3 changed files with 37 additions and 8 deletions

View file

@ -1,6 +1,8 @@
package mage.cards.o; package mage.cards.o;
import mage.MageInt; import mage.MageInt;
import mage.MageItem;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.common.DiscardedByOpponentTriggeredAbility; import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
@ -18,8 +20,10 @@ import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Controllable; import mage.game.Controllable;
import mage.game.Game; import mage.game.Game;
@ -85,6 +89,12 @@ enum OrvarTheAllFormCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast"); Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast");
MageObjectReference mor;
if (source.getSourceObjectZoneChangeCounter() == 0) {
mor = new MageObjectReference(source.getSourceId(), game);
} else {
mor = new MageObjectReference(source);
}
return spell != null && spell return spell != null && spell
.getSpellAbility() .getSpellAbility()
.getModes() .getModes()
@ -94,9 +104,9 @@ enum OrvarTheAllFormCondition implements Condition {
.flatMap(Collection::stream) .flatMap(Collection::stream)
.map(Target::getTargets) .map(Target::getTargets)
.flatMap(Collection::stream) .flatMap(Collection::stream)
.filter(uuid -> uuid != source.getSourceId())
.map(game::getPermanent) .map(game::getPermanent)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(p -> !mor.refersTo(p, game))
.map(Controllable::getControllerId) .map(Controllable::getControllerId)
.anyMatch(source::isControlledBy); .anyMatch(source::isControlledBy);
} }
@ -121,7 +131,7 @@ class OrvarTheAllFormEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Spell spell = (Spell) this.getValue("spellCast"); Spell spell = (Spell) this.getValue("spellCast");
if (spell == null) { if (player == null || spell == null) {
return false; return false;
} }
List<Predicate<Permanent>> predicates = spell List<Predicate<Permanent>> predicates = spell
@ -133,18 +143,17 @@ class OrvarTheAllFormEffect extends OneShotEffect {
.flatMap(Collection::stream) .flatMap(Collection::stream)
.map(Target::getTargets) .map(Target::getTargets)
.flatMap(Collection::stream) .flatMap(Collection::stream)
.filter(uuid -> uuid != source.getSourceId())
.map(game::getPermanent) .map(game::getPermanent)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(Controllable::getControllerId) .map(MageItem::getId)
.filter(source::isControlledBy)
.map(PermanentIdPredicate::new) .map(PermanentIdPredicate::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (predicates.isEmpty()) { if (predicates.isEmpty()) {
return false; return false;
} }
FilterPermanent filter = new FilterPermanent("a permanent targeted by this spell"); FilterPermanent filter = new FilterControlledPermanent("a permanent you control targeted by that spell");
filter.add(Predicates.or(predicates)); filter.add(Predicates.or(predicates));
filter.add(Predicates.not(new MageObjectReferencePredicate(new MageObjectReference(source))));
TargetPermanent target = new TargetPermanent(filter); TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true); target.setNotTarget(true);
player.choose(outcome, target, source.getSourceId(), game); player.choose(outcome, target, source.getSourceId(), game);

View file

@ -1,5 +1,6 @@
package mage; package mage;
import mage.abilities.Ability;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -52,6 +53,15 @@ public class MageObjectReference implements Comparable<MageObjectReference>, Ser
this.zoneChangeCounter = -1; this.zoneChangeCounter = -1;
} }
public MageObjectReference(Ability source) {
this(source, 0);
}
public MageObjectReference(Ability source, int modifier) {
this.sourceId = source.getSourceId();
this.zoneChangeCounter = source.getSourceObjectZoneChangeCounter() + modifier;
}
/** /**
* @param sourceId can be null * @param sourceId can be null
* @param game * @param game

View file

@ -31,8 +31,8 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
* *
* @param ability * @param ability
* @param condition * @param condition
* @param text explicit rule text for the ability, if null or empty, the * @param text explicit rule text for the ability, if null or empty, the
* rule text generated by the triggered ability itself is used. * rule text generated by the triggered ability itself is used.
*/ */
public ConditionalInterveningIfTriggeredAbility(TriggeredAbility ability, Condition condition, String text) { public ConditionalInterveningIfTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
super(ability.getZone(), null); super(ability.getZone(), null);
@ -112,4 +112,14 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
public boolean isOptional() { public boolean isOptional() {
return ability.isOptional(); return ability.isOptional();
} }
@Override
public void setSourceObjectZoneChangeCounter(int sourceObjectZoneChangeCounter) {
ability.setSourceObjectZoneChangeCounter(sourceObjectZoneChangeCounter);
}
@Override
public int getSourceObjectZoneChangeCounter() {
return ability.getSourceObjectZoneChangeCounter();
}
} }