mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
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:
@@ -775,6 +775,7 @@ public class GameAction {
|
|||||||
if (game.isGameOver()) {
|
if (game.isGameOver()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
game.getTracker().freeze(); //prevent views flickering during while updating for state-based effects
|
||||||
|
|
||||||
// remove old effects
|
// remove old effects
|
||||||
game.getStaticEffects().clearStaticEffects(affectedCards);
|
game.getStaticEffects().clearStaticEffects(affectedCards);
|
||||||
@@ -907,6 +908,7 @@ public class GameAction {
|
|||||||
if (runEvents && !affectedCards.isEmpty()) {
|
if (runEvents && !affectedCards.isEmpty()) {
|
||||||
game.fireEvent(new GameEventCardStatsChanged(affectedCards));
|
game.fireEvent(new GameEventCardStatsChanged(affectedCards));
|
||||||
}
|
}
|
||||||
|
game.getTracker().unfreeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void checkStateEffects(final boolean runEvents) {
|
public final void checkStateEffects(final boolean runEvents) {
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Spell.performanceMode && lkicheck) {
|
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));
|
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
|
// reset static abilities
|
||||||
if (!Spell.performanceMode && lkicheck) {
|
if (!Spell.performanceMode && lkicheck) {
|
||||||
game.getAction().checkStaticAbilities(false);
|
game.getAction().checkStaticAbilities(false);
|
||||||
|
game.getTracker().unfreeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(isInstant || activator.canCastSorcery() || flash || getRestrictions().isInstantSpeed()
|
if (!(isInstant || activator.canCastSorcery() || flash || getRestrictions().isInstantSpeed()
|
||||||
|
|||||||
@@ -65,9 +65,17 @@ public abstract class TrackableObject implements IIdentifiable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final <T> void set(final TrackableProperty key, final T value) {
|
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
|
if (tracker != null && tracker.isFrozen()) { //if trackable objects currently frozen, queue up delayed prop change
|
||||||
tracker.addDelayedPropChange(this, key, value);
|
boolean respectsFreeze = false;
|
||||||
return;
|
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 (value == null || value.equals(key.getDefaultValue())) {
|
||||||
if (props.remove(key) != null) {
|
if (props.remove(key) != null) {
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ public enum TrackableProperty {
|
|||||||
ChosenMode(TrackableTypes.StringType),
|
ChosenMode(TrackableTypes.StringType),
|
||||||
Remembered(TrackableTypes.StringType),
|
Remembered(TrackableTypes.StringType),
|
||||||
NamedCard(TrackableTypes.StringType),
|
NamedCard(TrackableTypes.StringType),
|
||||||
PlayerMayLook(TrackableTypes.PlayerViewCollectionType, false),
|
PlayerMayLook(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType, false),
|
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Equipping(TrackableTypes.CardViewType),
|
Equipping(TrackableTypes.CardViewType),
|
||||||
EquippedBy(TrackableTypes.CardViewCollectionType),
|
EquippedBy(TrackableTypes.CardViewCollectionType),
|
||||||
Enchanting(TrackableTypes.GameEntityViewType),
|
Enchanting(TrackableTypes.GameEntityViewType),
|
||||||
@@ -57,7 +57,7 @@ public enum TrackableProperty {
|
|||||||
Haunting(TrackableTypes.CardViewType),
|
Haunting(TrackableTypes.CardViewType),
|
||||||
MustBlockCards(TrackableTypes.CardViewCollectionType),
|
MustBlockCards(TrackableTypes.CardViewCollectionType),
|
||||||
PairedWith(TrackableTypes.CardViewType),
|
PairedWith(TrackableTypes.CardViewType),
|
||||||
CurrentState(TrackableTypes.CardStateViewType, false), //can't respect freeze, otherwise card constructor can crash
|
CurrentState(TrackableTypes.CardStateViewType, FreezeMode.IgnoresFreezeIfUnset),
|
||||||
AlternateState(TrackableTypes.CardStateViewType),
|
AlternateState(TrackableTypes.CardStateViewType),
|
||||||
HiddenId(TrackableTypes.IntegerType),
|
HiddenId(TrackableTypes.IntegerType),
|
||||||
ExertedThisTurn(TrackableTypes.BooleanType),
|
ExertedThisTurn(TrackableTypes.BooleanType),
|
||||||
@@ -100,19 +100,19 @@ public enum TrackableProperty {
|
|||||||
MaxHandSize(TrackableTypes.IntegerType),
|
MaxHandSize(TrackableTypes.IntegerType),
|
||||||
HasUnlimitedHandSize(TrackableTypes.BooleanType),
|
HasUnlimitedHandSize(TrackableTypes.BooleanType),
|
||||||
NumDrawnThisTurn(TrackableTypes.IntegerType),
|
NumDrawnThisTurn(TrackableTypes.IntegerType),
|
||||||
Keywords(TrackableTypes.KeywordCollectionViewType, false),
|
Keywords(TrackableTypes.KeywordCollectionViewType, FreezeMode.IgnoresFreeze),
|
||||||
Commander(TrackableTypes.CardViewCollectionType, false),
|
Commander(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
CommanderDamage(TrackableTypes.IntegerMapType),
|
CommanderDamage(TrackableTypes.IntegerMapType),
|
||||||
MindSlaveMaster(TrackableTypes.PlayerViewType),
|
MindSlaveMaster(TrackableTypes.PlayerViewType),
|
||||||
Ante(TrackableTypes.CardViewCollectionType, false),
|
Ante(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
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
|
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, false),
|
Command(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Exile(TrackableTypes.CardViewCollectionType, false),
|
Exile(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Flashback(TrackableTypes.CardViewCollectionType, false),
|
Flashback(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Graveyard(TrackableTypes.CardViewCollectionType, false),
|
Graveyard(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Hand(TrackableTypes.CardViewCollectionType, false),
|
Hand(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Library(TrackableTypes.CardViewCollectionType, false),
|
Library(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Mana(TrackableTypes.ManaMapType, false),
|
Mana(TrackableTypes.ManaMapType, FreezeMode.IgnoresFreeze),
|
||||||
|
|
||||||
//SpellAbility
|
//SpellAbility
|
||||||
HostCard(TrackableTypes.CardViewType),
|
HostCard(TrackableTypes.CardViewType),
|
||||||
@@ -132,12 +132,12 @@ public enum TrackableProperty {
|
|||||||
OptionalTrigger(TrackableTypes.BooleanType),
|
OptionalTrigger(TrackableTypes.BooleanType),
|
||||||
|
|
||||||
//Combat
|
//Combat
|
||||||
AttackersWithDefenders(TrackableTypes.GenericMapType, false),
|
AttackersWithDefenders(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
AttackersWithBlockers(TrackableTypes.GenericMapType, false),
|
AttackersWithBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
BandsWithDefenders(TrackableTypes.GenericMapType, false),
|
BandsWithDefenders(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
BandsWithBlockers(TrackableTypes.GenericMapType, false),
|
BandsWithBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
AttackersWithPlannedBlockers(TrackableTypes.GenericMapType, false),
|
AttackersWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
BandsWithPlannedBlockers(TrackableTypes.GenericMapType, false),
|
BandsWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze),
|
||||||
|
|
||||||
//Game
|
//Game
|
||||||
Players(TrackableTypes.PlayerViewCollectionType),
|
Players(TrackableTypes.PlayerViewCollectionType),
|
||||||
@@ -157,19 +157,25 @@ public enum TrackableProperty {
|
|||||||
PlayerTurn(TrackableTypes.PlayerViewType),
|
PlayerTurn(TrackableTypes.PlayerViewType),
|
||||||
Phase(TrackableTypes.EnumType(PhaseType.class));
|
Phase(TrackableTypes.EnumType(PhaseType.class));
|
||||||
|
|
||||||
|
public enum FreezeMode {
|
||||||
|
IgnoresFreeze,
|
||||||
|
RespectsFreeze,
|
||||||
|
IgnoresFreezeIfUnset
|
||||||
|
}
|
||||||
|
|
||||||
private final TrackableType<?> type;
|
private final TrackableType<?> type;
|
||||||
private final boolean respectFreeze;
|
private final FreezeMode freezeMode;
|
||||||
|
|
||||||
private TrackableProperty(TrackableType<?> type0) {
|
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;
|
type = type0;
|
||||||
respectFreeze = respectFreeze0;
|
freezeMode = freezeMode0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean respectFreeze() {
|
public FreezeMode getFreezeMode() {
|
||||||
return respectFreeze;
|
return freezeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -1995,6 +1995,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
fstream.close();
|
fstream.close();
|
||||||
} catch (final FileNotFoundException fnfe) {
|
} catch (final FileNotFoundException fnfe) {
|
||||||
SOptionPane.showErrorDialog("File not found: " + filename);
|
SOptionPane.showErrorDialog("File not found: " + filename);
|
||||||
|
return;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
SOptionPane.showErrorDialog("Error loading battle setup file!");
|
SOptionPane.showErrorDialog("Error loading battle setup file!");
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user