* Switched from UUID to MageObjectReference to handle affected objects of continuous effects. Solvng problems with objects that changed (multiple times) zones while the effect lasts.

This commit is contained in:
LevelX2 2014-12-25 02:03:21 +01:00
parent 9ff1f60903
commit 02ba80b719
41 changed files with 407 additions and 342 deletions

View file

@ -128,4 +128,12 @@ public class MageObjectReference implements Comparable<MageObjectReference> {
return null;
}
public Card getCard(Game game) {
Card card = game.getPermanent(sourceId);
if (card != null && card.getZoneChangeCounter() == zoneChangeCounter) {
return card;
}
return null;
}
}

View file

@ -28,16 +28,14 @@
package mage.abilities.effects;
import java.util.List;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.SubLayer;
import mage.abilities.Ability;
import mage.game.Game;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
@ -57,7 +55,7 @@ public interface ContinuousEffect extends Effect {
Layer getLayer();
SubLayer getSublayer();
void overrideRuleText(String text);
List<UUID> getAffectedObjects();
List<MageObjectReference> getAffectedObjects();
@Override
void newId();

View file

@ -29,6 +29,7 @@
package mage.abilities.effects.common.continious;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
@ -49,7 +50,6 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
protected Token token;
protected String type;
protected int zoneChangeCounter;
public BecomesCreatureSourceEffect(Token token, String type, Duration duration) {
super(duration, Outcome.BecomeCreature);
@ -62,7 +62,6 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
super(effect);
this.token = effect.token.copy();
this.type = effect.type;
this.zoneChangeCounter = effect.zoneChangeCounter;
}
@Override
@ -73,17 +72,20 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
@Override
public void init(Ability source, Game game) {
super.init(source, game);
this.getAffectedObjects().add(source.getSourceId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
this.zoneChangeCounter = permanent.getZoneChangeCounter();
if (affectedObjectsSet) {
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game));
}
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null && permanent.getZoneChangeCounter() == this.zoneChangeCounter) {
Permanent permanent;
if (affectedObjectsSet) {
permanent = affectedObjectList.get(0).getPermanent(game);
} else {
permanent = game.getPermanent(source.getSourceId());
}
if (permanent != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {

View file

@ -61,7 +61,6 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
protected Map<UUID,Ability> turnFaceUpAbilityMap = new HashMap<>();
protected FilterPermanent filter;
protected ArrayList<MageObjectReference> objectList = new ArrayList<>();
public BecomesFaceDownCreatureAllEffect(FilterPermanent filter) {
super(Duration.EndOfGame, Outcome.BecomeCreature);
@ -71,7 +70,6 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
public BecomesFaceDownCreatureAllEffect(final BecomesFaceDownCreatureAllEffect effect) {
super(effect);
this.objectList.addAll(effect.objectList);
for (Map.Entry<UUID,Ability> entry: effect.turnFaceUpAbilityMap.entrySet()) {
this.turnFaceUpAbilityMap.put(entry.getKey(), entry.getValue());
}
@ -88,7 +86,7 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
super.init(source, game);
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!perm.isFaceDown()) {
objectList.add(new MageObjectReference(perm));
affectedObjectList.add(new MageObjectReference(perm));
perm.setFaceDown(true);
// check for Morph
Card card = game.getCard(perm.getId());
@ -106,7 +104,7 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl imple
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
boolean targetExists = false;
for (MageObjectReference mor: objectList) {
for (MageObjectReference mor: affectedObjectList) {
Permanent permanent = mor.getPermanent(game);
if (permanent != null && permanent.isFaceDown()) {
targetExists = true;

View file

@ -29,7 +29,7 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
@ -113,7 +113,7 @@ public class BoostAllEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -126,9 +126,8 @@ public class BoostAllEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
if (this.affectedObjectsSet) {
for (Iterator<UUID> it = objects.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
UUID permanentId = it.next();
Permanent permanent = game.getPermanent(permanentId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.addPower(power.calculate(game, source, this));
permanent.addToughness(toughness.calculate(game, source, this));

View file

@ -29,7 +29,7 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
@ -116,7 +116,7 @@ public class BoostControlledEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -129,9 +129,8 @@ public class BoostControlledEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
if (this.affectedObjectsSet) {
for (Iterator<UUID> it = objects.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
UUID permanentId = it.next();
Permanent permanent = game.getPermanent(permanentId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.addPower(power.calculate(game, source, this));
permanent.addToughness(toughness.calculate(game, source, this));

View file

@ -1,5 +1,6 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.Duration;
@ -12,6 +13,7 @@ import mage.game.permanent.Permanent;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
public class BoostOpponentsEffect extends ContinuousEffectImpl {
protected int power;
@ -49,7 +51,7 @@ public class BoostOpponentsEffect extends ContinuousEffectImpl {
Set<UUID> opponents = game.getOpponents(source.getControllerId());
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (opponents.contains(perm.getControllerId())) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -58,8 +60,20 @@ public class BoostOpponentsEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> opponents = game.getOpponents(source.getControllerId());
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
if (this.affectedObjectsSet) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent perm = it.next().getPermanent(game);
if (perm != null) {
if (opponents.contains(perm.getControllerId())) {
perm.addPower(power);
perm.addToughness(toughness);
}
} else {
it.remove();
}
}
} else {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (opponents.contains(perm.getControllerId())) {
perm.addPower(power);
perm.addToughness(toughness);

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common.continious;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
@ -85,7 +86,9 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff
@Override
public void init(Ability source, Game game) {
super.init(source, game);
getAffectedObjects().add(source.getSourceId());
if (affectedObjectsSet) {
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game));
}
if (lockedIn) {
power = new StaticValue(power.calculate(game, source, this));
toughness = new StaticValue(toughness.calculate(game, source, this));
@ -94,7 +97,12 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(source.getSourceId());
Permanent target;
if (affectedObjectsSet) {
target = affectedObjectList.get(0).getPermanent(game);
} else {
target = game.getPermanent(source.getSourceId());
}
if (target != null) {
target.addPower(power.calculate(game, source, this));
target.addToughness(toughness.calculate(game, source, this));

View file

@ -28,6 +28,8 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import mage.MageObjectReference;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
@ -84,7 +86,7 @@ public class GainAbilityAllEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -97,8 +99,17 @@ public class GainAbilityAllEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
if (this.affectedObjectsSet) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
} else {
it.remove(); // no longer on the battlefield, remove reference to object
}
}
} else {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
perm.addAbility(ability, source.getSourceId(), game);
}

View file

@ -28,6 +28,8 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import mage.MageObjectReference;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
@ -89,7 +91,7 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -102,8 +104,19 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
if (this.affectedObjectsSet) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent perm = it.next().getPermanent(game);
if (perm != null) {
for (Ability abilityToAdd : ability) {
perm.addAbility(abilityToAdd, source.getSourceId(), game);
}
} else {
it.remove(); // no longer on the battlefield, remove reference to object
}
}
} else {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
for (Ability abilityToAdd : ability) {
perm.addAbility(abilityToAdd, source.getSourceId(), game);

View file

@ -27,6 +27,7 @@
*/
package mage.abilities.effects.common.continious;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
@ -90,13 +91,20 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou
@Override
public void init(Ability source, Game game) {
super.init(source, game);
getAffectedObjects().add(source.getSourceId());
if (affectedObjectsSet) {
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game));
}
}
@Override
public boolean apply(Game game, Ability source) {
if (onCard) {
Card card = game.getCard(source.getSourceId());
Card card;
if (affectedObjectsSet) {
card = affectedObjectList.get(0).getCard(game);
} else {
card = game.getCard(source.getSourceId());
}
if (card != null) {
// add ability to card only once
card.addAbility(ability);
@ -104,15 +112,20 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou
return true;
}
} else {
Permanent permanent = game.getPermanent(source.getSourceId());
Permanent permanent;
if (affectedObjectsSet) {
permanent = affectedObjectList.get(0).getPermanent(game);
} else {
permanent = game.getPermanent(source.getSourceId());
}
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
return true;
}
if (duration.equals(Duration.Custom)) {
this.discard();
}
}
return false;
if (duration.equals(Duration.Custom)) {
this.discard();
}
return true;
}
}

View file

@ -29,22 +29,21 @@
package mage.abilities.effects.common.continious;
import java.util.Locale;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import java.util.UUID;
import mage.cards.Card;
import mage.constants.PhaseStep;
import mage.game.turn.Step;
/**
*
* @author BetaSteward_at_googlemail.com
@ -139,8 +138,16 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
} else {
for (UUID permanentId : targetPointer.getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
boolean shortLivingLKI = false;
if (permanent == null) {
permanent = (Permanent) game.getShortLivingLKI(permanentId, Zone.BATTLEFIELD);
shortLivingLKI = true;
}
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
if (shortLivingLKI) { // needed for undying because TriggeredAbilities checks if the permanent has still the ability
game.rememberLKI(permanentId, Zone.BATTLEFIELD, permanent);
}
affectedTargets++;
}
}

View file

@ -28,8 +28,10 @@
package mage.abilities.effects.common.continious;
import java.util.Iterator;
import java.util.Locale;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue;
@ -89,7 +91,7 @@ public class SetPowerToughnessAllEffect extends ContinuousEffectImpl {
super.init(source, game);
if (affectedObjectsSet) {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm));
}
}
if (lockedInPT) {
@ -103,11 +105,13 @@ public class SetPowerToughnessAllEffect extends ContinuousEffectImpl {
int newPower = power.calculate(game, source, this);
int newToughness = toughness.calculate(game, source, this);
if (affectedObjectsSet) {
for (UUID permanentId :objects) {
Permanent permanent = game.getPermanent(permanentId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.getPower().setValue(newPower);
permanent.getToughness().setValue(newToughness);
} else {
it.remove(); // no longer on the battlefield, remove reference to object
}
}
} else {

View file

@ -29,8 +29,10 @@
package mage.abilities.effects.common.continious;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
@ -71,8 +73,8 @@ public class SwitchPowerToughnessAllEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (Permanent creature :game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
this.objects.add(creature.getId());
for (Permanent perm :game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
affectedObjectList.add(new MageObjectReference(perm));
}
}
}
@ -83,18 +85,16 @@ public class SwitchPowerToughnessAllEffect extends ContinuousEffectImpl {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (this.affectedObjectsSet) {
Set<UUID> toDelete = new HashSet<>();
for (UUID creatureId: objects) {
Permanent creature = game.getPermanent(creatureId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent creature = it.next().getPermanent(game);
if (creature != null) {
int power = creature.getPower().getValue();
creature.getPower().setValue(creature.getToughness().getValue());
creature.getToughness().setValue(power);
} else {
toDelete.add(creatureId);
it.remove();
}
}
this.objects.removeAll(toDelete);
}
} else {
for (Permanent creature :game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
int power = creature.getPower().getValue();