forked from External/mage
fix ContinuousEffect that access affectedObjectsSet before it is initialized (#12080)
This commit is contained in:
parent
cce7f79d89
commit
017286ed94
47 changed files with 351 additions and 150 deletions
|
|
@ -37,7 +37,9 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
// If your ability/effect supports multi use cases (one time use, static, target pointers) then affectedObjectsSet can be useful:
|
||||
// * affectedObjectsSet - true on static objects and false on dynamic objects (see rules from 611.2c)
|
||||
// Full implement example: GainAbilityTargetEffect
|
||||
protected boolean affectedObjectsSet = false;
|
||||
//
|
||||
// is null before being initialized. Any access attempt computes it.
|
||||
private Boolean affectedObjectsSet = null;
|
||||
protected List<MageObjectReference> affectedObjectList = new ArrayList<>();
|
||||
|
||||
protected boolean temporary = false;
|
||||
|
|
@ -62,7 +64,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
private int effectStartingStepNum = 0; // Some continuous are waiting for the next step of a kind.
|
||||
// Avoid miscancelling if the start step is of that kind.
|
||||
|
||||
public ContinuousEffectImpl(Duration duration, Outcome outcome) {
|
||||
protected ContinuousEffectImpl(Duration duration, Outcome outcome) {
|
||||
super(outcome);
|
||||
this.duration = duration;
|
||||
this.order = 0;
|
||||
|
|
@ -71,7 +73,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
this.dependendToTypes = EnumSet.noneOf(DependencyType.class);
|
||||
}
|
||||
|
||||
public ContinuousEffectImpl(Duration duration, Layer layer, SubLayer sublayer, Outcome outcome) {
|
||||
protected ContinuousEffectImpl(Duration duration, Layer layer, SubLayer sublayer, Outcome outcome) {
|
||||
this(duration, outcome);
|
||||
this.layer = layer;
|
||||
this.sublayer = sublayer;
|
||||
|
|
@ -166,6 +168,16 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
@Override
|
||||
public void init(Ability source, Game game, UUID activePlayerId) {
|
||||
getTargetPointer().init(game, source);
|
||||
if (this.affectedObjectsSet == null) {
|
||||
initAffectedObjectsSet(source);
|
||||
}
|
||||
setStartingControllerAndTurnNum(game, source.getControllerId(), activePlayerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes affectedObjectsSet boolean from the source object.
|
||||
*/
|
||||
private void initAffectedObjectsSet(Ability source) {
|
||||
// 20210112 - 611.2c
|
||||
// 611.2c If a continuous effect generated by the resolution of a spell or ability modifies the
|
||||
// characteristics or changes the controller of any objects, the set of objects it affects is
|
||||
|
|
@ -177,6 +189,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
// effect began.If a single continuous effect has parts that modify the characteristics or
|
||||
// changes the controller of any objects and other parts that don’t, the set of objects
|
||||
// each part applies to is determined independently.
|
||||
this.affectedObjectsSet = false;
|
||||
if (AbilityType.STATIC != source.getAbilityType()) {
|
||||
if (layer != null) {
|
||||
switch (layer) {
|
||||
|
|
@ -199,7 +212,35 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
this.affectedObjectsSet = true;
|
||||
}
|
||||
}
|
||||
setStartingControllerAndTurnNum(game, source.getControllerId(), activePlayerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a workaround when trying to access affectObjectsSet during init, before
|
||||
* ContinuousEffectImpl::init is called.
|
||||
* <p>
|
||||
* TODO: should be investigated how to modify all continuous effects to call super.init()
|
||||
* before doing their own changes. At which point there is no longer need for this
|
||||
* workaround.
|
||||
*/
|
||||
protected boolean getAffectedObjectsSetAtInit(Ability source) {
|
||||
if (this.affectedObjectsSet == null) {
|
||||
initAffectedObjectsSet(source);
|
||||
}
|
||||
return this.affectedObjectsSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this getter in other places than overriden calls, most likely the apply method.
|
||||
*/
|
||||
protected boolean getAffectedObjectsSet() {
|
||||
if (this.affectedObjectsSet == null) {
|
||||
return false;
|
||||
}
|
||||
return this.affectedObjectsSet;
|
||||
}
|
||||
|
||||
protected void setAffectedObjectsSet(boolean affectedObjectsSet) {
|
||||
this.affectedObjectsSet = affectedObjectsSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue