Fixed handling of Guardian Beast, fixed rule text display (fixes #5922).

This commit is contained in:
LevelX2 2019-12-14 22:20:59 +01:00
parent 294374e952
commit 515b55f088
4 changed files with 58 additions and 29 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.g;
import java.util.Objects;
@ -18,6 +17,7 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterObject;
import mage.filter.FilterStackObject;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledArtifactPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -49,11 +49,15 @@ public final class GuardianBeast extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them. This effect doesn't remove Auras already attached to those artifacts.
Effect effect = new ConditionalContinuousEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield, filter), new InvertCondition(SourceTappedCondition.instance), "noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them");
GuardianBeastConditionalEffect effect2 = new GuardianBeastConditionalEffect(this.getId());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect2));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them.
// This effect doesn't remove Auras already attached to those artifacts.
Effect effect = new ConditionalContinuousEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield, filter),
new InvertCondition(SourceTappedCondition.instance),
"As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
ability.addEffect(new GuardianBeastConditionalEffect(this.getId()));
this.addAbility(ability);
}
public GuardianBeast(final GuardianBeast card) {
@ -68,16 +72,11 @@ public final class GuardianBeast extends CardImpl {
class GuardianBeastConditionalEffect extends ContinuousRuleModifyingEffectImpl {
private static final FilterControlledArtifactPermanent filter = new FilterControlledArtifactPermanent("Noncreature artifacts");
private UUID guardianBeastId;
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
private final UUID guardianBeastId;
public GuardianBeastConditionalEffect(UUID guardianBeastId) {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
staticText = "Noncreature artifacts you control have they can't be enchanted, they're indestructible, and other players can't gain control of them";
staticText = ", and other players can't gain control of them. This effect doesn't remove Auras already attached to those artifacts";
this.guardianBeastId = guardianBeastId;
}
@ -116,8 +115,11 @@ class GuardianBeastConditionalEffect extends ContinuousRuleModifyingEffectImpl {
}
StackObject spell = game.getStack().getStackObject(event.getSourceId());
if (event.getType() == EventType.LOSE_CONTROL || event.getType() == EventType.ATTACH || event.getType() == EventType.TARGET && spell != null && spell.isEnchantment() && spell.hasSubtype(SubType.AURA, game)) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (event.getType() == EventType.GAIN_CONTROL
|| ((event.getType() == EventType.ATTACH
|| event.getType() == EventType.TARGET)
&& spell != null && spell.isEnchantment() && spell.hasSubtype(SubType.AURA, game))) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_ARTIFACTS_NON_CREATURE, source.getControllerId(), game)) {
if (perm != null && Objects.equals(perm.getId(), targetPermanent.getId()) && !perm.isCreature()) {
return true;
}

View file

@ -2,6 +2,7 @@ package mage.abilities.effects.common.continuous;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.Duration;
@ -23,6 +24,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
protected UUID controllingPlayerId;
private boolean fixedControl;
private boolean firstControlChange = true;
public GainControlTargetEffect(Duration duration) {
this(duration, false, null);
@ -77,31 +79,44 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
boolean targetStillExists = false;
boolean oneTargetStillExists = false;
for (UUID permanentId : getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
targetStillExists = true;
oneTargetStillExists = true;
if (!permanent.isControlledBy(controllingPlayerId)) {
GameEvent loseControlEvent = GameEvent.getEvent(GameEvent.EventType.LOSE_CONTROL, permanentId, source.getId(), permanent.getControllerId());
if (game.replaceEvent(loseControlEvent)) {
return false;
}
boolean controlChanged = false;
if (controllingPlayerId != null) {
permanent.changeControllerId(controllingPlayerId, game);
if (permanent.changeControllerId(controllingPlayerId, game)) {
permanent.getAbilities().setControllerId(controllingPlayerId);
controlChanged = true;
}
} else {
permanent.changeControllerId(source.getControllerId(), game);
if (permanent.changeControllerId(source.getControllerId(), game)) {
permanent.getAbilities().setControllerId(source.getControllerId());
controlChanged = true;
}
}
if (source instanceof ActivatedAbility
&& firstControlChange && !controlChanged) {
// If it was not possible to get control of target permanent by the activated ability the first time it took place
// the effect failed (e.g. because of Guardian Beast) and must be discarded
// This does not handle correctly multiple targets at once
discard();
}
}
}
}
// no valid target exists and the controller is no longer in the game, effect can be discarded
if (!targetStillExists
if (!oneTargetStillExists
|| !controller.isInGame()) {
discard();
}
firstControlChange = false;
return true;
}
discard(); // controller no longer exists

View file

@ -133,7 +133,6 @@ public final class StaticFilters {
FILTER_CARD_A_NON_LAND.setLockedFilter(true);
}
public static final FilterNonlandCard FILTER_CARDS_NON_LAND = new FilterNonlandCard("nonland cards");
static {
@ -188,6 +187,13 @@ public final class StaticFilters {
FILTER_ARTIFACT_CREATURE_PERMANENT.setLockedFilter(true);
}
public static final FilterControlledArtifactPermanent FILTER_ARTIFACTS_NON_CREATURE = new FilterControlledArtifactPermanent("Noncreature artifacts");
static {
FILTER_ARTIFACTS_NON_CREATURE.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
FILTER_ARTIFACTS_NON_CREATURE.setLockedFilter(true);
}
public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature");
static {

View file

@ -1,5 +1,6 @@
package mage.game.permanent;
import java.util.*;
import mage.MageObject;
import mage.MageObjectReference;
import mage.ObjectColor;
@ -37,8 +38,6 @@ import mage.util.GameLog;
import mage.util.ThreadLocalStringBuilder;
import org.apache.log4j.Logger;
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -665,6 +664,13 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
@Override
public boolean changeControllerId(UUID controllerId, Game game) {
Player newController = game.getPlayer(controllerId);
// For each control change compared to last controler send a GAIN_CONTROL replace event to be able to prevent the gain control (e.g. Guardian Beast)
if (beforeResetControllerId != controllerId) {
GameEvent gainControlEvent = GameEvent.getEvent(GameEvent.EventType.GAIN_CONTROL, this.getId(), null, controllerId);
if (game.replaceEvent(gainControlEvent)) {
return false;
}
}
GameEvent loseControlEvent = GameEvent.getEvent(GameEvent.EventType.LOSE_CONTROL, this.getId(), null, controllerId);