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

@ -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);
permanent.getAbilities().setControllerId(controllingPlayerId);
if (permanent.changeControllerId(controllingPlayerId, game)) {
permanent.getAbilities().setControllerId(controllingPlayerId);
controlChanged = true;
}
} else {
permanent.changeControllerId(source.getControllerId(), game);
permanent.getAbilities().setControllerId(source.getControllerId());
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);
@ -755,7 +761,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
this.attachedTo = attachToObjectId;
this.attachedToZoneChangeCounter = game.getState().getZoneChangeCounter(attachToObjectId);
for (Ability ability : this.getAbilities()) {
for (Iterator<Effect> ite = ability.getEffects(game, EffectType.CONTINUOUS).iterator(); ite.hasNext(); ) {
for (Iterator<Effect> ite = ability.getEffects(game, EffectType.CONTINUOUS).iterator(); ite.hasNext();) {
ContinuousEffect effect = (ContinuousEffect) ite.next();
game.getContinuousEffects().setOrder(effect);
// It's important to update the timestamp of the copied effect in ContinuousEffects because it does the action
@ -810,8 +816,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
* @param game
* @param preventable
* @param combat
* @param markDamage If true, damage will be dealt later in applyDamage
* method
* @param markDamage If true, damage will be dealt later in applyDamage
* method
* @return
*/
private int damage(int damageAmount, UUID sourceId, Game game, boolean preventable, boolean combat, boolean markDamage, List<UUID> appliedEffects) {