mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Prevent P/T flickering for good
This commit is contained in:
@@ -48,6 +48,7 @@ import forge.game.zone.PlayerZoneBattlefield;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.CollectionSuppliers;
|
||||
import forge.util.Expressions;
|
||||
@@ -659,6 +660,7 @@ public class GameAction {
|
||||
|
||||
final boolean refreeze = game.getStack().isFrozen();
|
||||
game.getStack().setFrozen(true);
|
||||
TrackableObject.freeze(); //prevent views flickering during while updating for state-based effects
|
||||
|
||||
// do this multiple times, sometimes creatures/permanents will survive
|
||||
// when they shouldn't
|
||||
@@ -750,14 +752,16 @@ public class GameAction {
|
||||
}
|
||||
} // for q=0;q<9
|
||||
|
||||
TrackableObject.unfreeze();
|
||||
|
||||
if (runEvents) {
|
||||
game.fireEvent(new GameEventCardStatsChanged(allAffectedCards));
|
||||
}
|
||||
|
||||
checkGameOverCondition();
|
||||
if (game.getAge() != GameStage.Play)
|
||||
if (game.getAge() != GameStage.Play) {
|
||||
return Collections.emptySet();
|
||||
|
||||
}
|
||||
game.getTriggerHandler().resetActiveTriggers();
|
||||
if (!refreeze) {
|
||||
game.getStack().unfreezeStack();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package forge.trackable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
|
||||
@@ -7,6 +8,32 @@ import forge.game.IIdentifiable;
|
||||
|
||||
//base class for objects that can be tracked and synced between game server and GUI
|
||||
public abstract class TrackableObject implements IIdentifiable {
|
||||
private static int freezeCounter = 0;
|
||||
public static void freeze() {
|
||||
freezeCounter++;
|
||||
}
|
||||
public static void unfreeze() {
|
||||
if (freezeCounter == 0 || --freezeCounter > 0 || delayedPropChanges.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
//after being unfrozen, ensure all changes delayed during freeze are now applied
|
||||
for (DelayedPropChange change : delayedPropChanges) {
|
||||
change.object.set(change.prop, change.value);
|
||||
}
|
||||
delayedPropChanges.clear();
|
||||
}
|
||||
private static class DelayedPropChange {
|
||||
private final TrackableObject object;
|
||||
private final TrackableProperty prop;
|
||||
private final Object value;
|
||||
private DelayedPropChange(TrackableObject object0, TrackableProperty prop0, Object value0) {
|
||||
object = object0;
|
||||
prop = prop0;
|
||||
value = value0;
|
||||
}
|
||||
}
|
||||
private static final ArrayList<DelayedPropChange> delayedPropChanges = new ArrayList<DelayedPropChange>();
|
||||
|
||||
private final int id;
|
||||
private final EnumMap<TrackableProperty, Object> props;
|
||||
private final EnumSet<TrackableProperty> changedProps;
|
||||
@@ -36,6 +63,10 @@ public abstract class TrackableObject implements IIdentifiable {
|
||||
}
|
||||
|
||||
protected <T> void set(TrackableProperty key, T value) {
|
||||
if (freezeCounter > 0 && key.respectFreeze()) { //if trackable objects currently frozen, queue up delayed prop change
|
||||
delayedPropChanges.add(new DelayedPropChange(this, key, value));
|
||||
return;
|
||||
}
|
||||
if (value == null || value.equals(key.getDefaultValue())) {
|
||||
if (props.remove(key) != null) {
|
||||
changedProps.add(key);
|
||||
|
||||
@@ -52,7 +52,7 @@ public enum TrackableProperty {
|
||||
Haunting(TrackableTypes.CardViewType),
|
||||
MustBlockCards(TrackableTypes.CardViewCollectionType),
|
||||
PairedWith(TrackableTypes.CardViewType),
|
||||
CurrentState(TrackableTypes.CardStateViewType),
|
||||
CurrentState(TrackableTypes.CardStateViewType, false), //can't respect freeze, otherwise card constructor can crash
|
||||
AlternateState(TrackableTypes.CardStateViewType),
|
||||
|
||||
//Card State
|
||||
@@ -140,9 +140,18 @@ public enum TrackableProperty {
|
||||
Phase(TrackableTypes.EnumType(PhaseType.class));
|
||||
|
||||
private final TrackableType<?> type;
|
||||
private final boolean respectFreeze;
|
||||
|
||||
private TrackableProperty(TrackableType<?> type0) {
|
||||
this(type0, true);
|
||||
}
|
||||
private TrackableProperty(TrackableType<?> type0, boolean respectFreeze0) {
|
||||
type = type0;
|
||||
respectFreeze = respectFreeze0;
|
||||
}
|
||||
|
||||
public boolean respectFreeze() {
|
||||
return respectFreeze;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
Reference in New Issue
Block a user