Merge branch 'master' into 'master'

Prevent views flickering during gameplay from state-based effects.

See merge request core-developers/forge!563
This commit is contained in:
austinio7116
2018-05-18 18:58:24 +00:00
5 changed files with 48 additions and 29 deletions

View File

@@ -775,6 +775,7 @@ public class GameAction {
if (game.isGameOver()) {
return;
}
game.getTracker().freeze(); //prevent views flickering during while updating for state-based effects
// remove old effects
game.getStaticEffects().clearStaticEffects(affectedCards);
@@ -907,6 +908,7 @@ public class GameAction {
if (runEvents && !affectedCards.isEmpty()) {
game.fireEvent(new GameEventCardStatsChanged(affectedCards));
}
game.getTracker().unfreeze();
}
public final void checkStateEffects(final boolean runEvents) {

View File

@@ -123,6 +123,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
}
if (!Spell.performanceMode && lkicheck) {
game.getTracker().freeze(); //prevent views flickering during while updating for state-based effects
game.getAction().checkStaticAbilities(false, Sets.newHashSet(card), new CardCollection(card));
}
@@ -131,6 +132,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
// reset static abilities
if (!Spell.performanceMode && lkicheck) {
game.getAction().checkStaticAbilities(false);
game.getTracker().unfreeze();
}
if (!(isInstant || activator.canCastSorcery() || flash || getRestrictions().isInstantSpeed()

View File

@@ -65,9 +65,17 @@ public abstract class TrackableObject implements IIdentifiable, Serializable {
}
protected final <T> void set(final TrackableProperty key, final T value) {
if (tracker != null && tracker.isFrozen() && key.respectFreeze()) { //if trackable objects currently frozen, queue up delayed prop change
tracker.addDelayedPropChange(this, key, value);
return;
if (tracker != null && tracker.isFrozen()) { //if trackable objects currently frozen, queue up delayed prop change
boolean respectsFreeze = false;
if (key.getFreezeMode() == TrackableProperty.FreezeMode.RespectsFreeze) {
respectsFreeze = true;
} else if (key.getFreezeMode() == TrackableProperty.FreezeMode.IgnoresFreezeIfUnset) {
respectsFreeze = (props.get(key) != null);
}
if (respectsFreeze) {
tracker.addDelayedPropChange(this, key, value);
return;
}
}
if (value == null || value.equals(key.getDefaultValue())) {
if (props.remove(key) != null) {

View File

@@ -41,8 +41,8 @@ public enum TrackableProperty {
ChosenMode(TrackableTypes.StringType),
Remembered(TrackableTypes.StringType),
NamedCard(TrackableTypes.StringType),
PlayerMayLook(TrackableTypes.PlayerViewCollectionType, false),
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType, false),
PlayerMayLook(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
Equipping(TrackableTypes.CardViewType),
EquippedBy(TrackableTypes.CardViewCollectionType),
Enchanting(TrackableTypes.GameEntityViewType),
@@ -57,7 +57,7 @@ public enum TrackableProperty {
Haunting(TrackableTypes.CardViewType),
MustBlockCards(TrackableTypes.CardViewCollectionType),
PairedWith(TrackableTypes.CardViewType),
CurrentState(TrackableTypes.CardStateViewType, false), //can't respect freeze, otherwise card constructor can crash
CurrentState(TrackableTypes.CardStateViewType, FreezeMode.IgnoresFreezeIfUnset),
AlternateState(TrackableTypes.CardStateViewType),
HiddenId(TrackableTypes.IntegerType),
ExertedThisTurn(TrackableTypes.BooleanType),
@@ -100,19 +100,19 @@ public enum TrackableProperty {
MaxHandSize(TrackableTypes.IntegerType),
HasUnlimitedHandSize(TrackableTypes.BooleanType),
NumDrawnThisTurn(TrackableTypes.IntegerType),
Keywords(TrackableTypes.KeywordCollectionViewType, false),
Commander(TrackableTypes.CardViewCollectionType, false),
Keywords(TrackableTypes.KeywordCollectionViewType, FreezeMode.IgnoresFreeze),
Commander(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
CommanderDamage(TrackableTypes.IntegerMapType),
MindSlaveMaster(TrackableTypes.PlayerViewType),
Ante(TrackableTypes.CardViewCollectionType, false),
Battlefield(TrackableTypes.CardViewCollectionType, false), //zones can't respect freeze, otherwise cards that die from state based effects won't have that reflected in the UI
Command(TrackableTypes.CardViewCollectionType, false),
Exile(TrackableTypes.CardViewCollectionType, false),
Flashback(TrackableTypes.CardViewCollectionType, false),
Graveyard(TrackableTypes.CardViewCollectionType, false),
Hand(TrackableTypes.CardViewCollectionType, false),
Library(TrackableTypes.CardViewCollectionType, false),
Mana(TrackableTypes.ManaMapType, false),
Ante(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Battlefield(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze), //zones can't respect freeze, otherwise cards that die from state based effects won't have that reflected in the UI
Command(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Exile(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Flashback(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Graveyard(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Hand(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Library(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
Mana(TrackableTypes.ManaMapType, FreezeMode.IgnoresFreeze),
//SpellAbility
HostCard(TrackableTypes.CardViewType),
@@ -132,12 +132,12 @@ public enum TrackableProperty {
OptionalTrigger(TrackableTypes.BooleanType),
//Combat
AttackersWithDefenders(TrackableTypes.GenericMapType, false),
AttackersWithBlockers(TrackableTypes.GenericMapType, false),
BandsWithDefenders(TrackableTypes.GenericMapType, false),
BandsWithBlockers(TrackableTypes.GenericMapType, false),
AttackersWithPlannedBlockers(TrackableTypes.GenericMapType, false),
BandsWithPlannedBlockers(TrackableTypes.GenericMapType, false),
AttackersWithDefenders(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
AttackersWithBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
BandsWithDefenders(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
BandsWithBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
AttackersWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
BandsWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
//Game
Players(TrackableTypes.PlayerViewCollectionType),
@@ -157,19 +157,25 @@ public enum TrackableProperty {
PlayerTurn(TrackableTypes.PlayerViewType),
Phase(TrackableTypes.EnumType(PhaseType.class));
public enum FreezeMode {
IgnoresFreeze,
RespectsFreeze,
IgnoresFreezeIfUnset
}
private final TrackableType<?> type;
private final boolean respectFreeze;
private final FreezeMode freezeMode;
private TrackableProperty(TrackableType<?> type0) {
this(type0, true);
this(type0, FreezeMode.RespectsFreeze);
}
private TrackableProperty(TrackableType<?> type0, boolean respectFreeze0) {
private TrackableProperty(TrackableType<?> type0, FreezeMode freezeMode0) {
type = type0;
respectFreeze = respectFreeze0;
freezeMode = freezeMode0;
}
public boolean respectFreeze() {
return respectFreeze;
public FreezeMode getFreezeMode() {
return freezeMode;
}
@SuppressWarnings("unchecked")

View File

@@ -1995,6 +1995,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
fstream.close();
} catch (final FileNotFoundException fnfe) {
SOptionPane.showErrorDialog("File not found: " + filename);
return;
} catch (final Exception e) {
SOptionPane.showErrorDialog("Error loading battle setup file!");
return;