From c5aa8cfae7cd907e65c80610f933023fdaab9923 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 30 Apr 2020 06:20:05 +0800 Subject: [PATCH] Fix Card Display on Network Client Adventure, Flip, Transform, Manifest, Morph etc display properly on Client Side (fix #159) Also Fix Aura Display I don't encounter issue #512 anyomre but I leave it open (limited testing) --- .../src/main/java/forge/game/GameView.java | 11 ++++-- .../game/event/GameEventCombatUpdate.java | 22 +++++++++++ .../forge/game/event/IGameEventVisitor.java | 2 + .../forge/trackable/TrackableProperty.java | 5 +++ .../java/forge/trackable/TrackableTypes.java | 37 +++++++++++++++++-- forge-gui-mobile/src/forge/Forge.java | 4 +- .../forge/screens/match/MatchController.java | 5 +-- .../control/FControlGameEventHandler.java | 17 +++++++++ .../java/forge/match/input/InputAttack.java | 4 ++ .../java/forge/match/input/InputBlock.java | 4 ++ 10 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/event/GameEventCombatUpdate.java diff --git a/forge-game/src/main/java/forge/game/GameView.java b/forge-game/src/main/java/forge/game/GameView.java index 0aad79f5cba..eda68175be6 100644 --- a/forge-game/src/main/java/forge/game/GameView.java +++ b/forge-game/src/main/java/forge/game/GameView.java @@ -24,7 +24,6 @@ import java.util.List; public class GameView extends TrackableObject { private static final long serialVersionUID = 8522884512960961528L; - private CombatView combatView; private final transient Game game; //TODO: Remove this when possible before network support added public GameView(final Game game0) { @@ -140,15 +139,18 @@ public class GameView extends TrackableObject { } public CombatView getCombat() { - return combatView; + return get(TrackableProperty.CombatView); + } + public void updateCombatView(CombatView combatView) { + set(TrackableProperty.CombatView, combatView); } void updateCombat(Combat combat) { if (combat == null) { - combatView = null; + set(TrackableProperty.CombatView, null); return; } - combatView = new CombatView(combat.getAttackingPlayer().getGame().getTracker()); + final CombatView combatView = new CombatView(combat.getAttackingPlayer().getGame().getTracker()); for (final AttackingBand b : combat.getAttackingBands()) { if (b == null) continue; final GameEntity defender = combat.getDefenderByAttacker(b); @@ -160,6 +162,7 @@ public class GameView extends TrackableObject { isBlocked ? CardView.getCollection(blockers) : null, CardView.getCollection(blockers)); } + updateCombatView(combatView); } public void serialize() { diff --git a/forge-game/src/main/java/forge/game/event/GameEventCombatUpdate.java b/forge-game/src/main/java/forge/game/event/GameEventCombatUpdate.java new file mode 100644 index 00000000000..ce71cea0105 --- /dev/null +++ b/forge-game/src/main/java/forge/game/event/GameEventCombatUpdate.java @@ -0,0 +1,22 @@ +package forge.game.event; + +import forge.game.card.Card; + +import java.util.List; + +public class GameEventCombatUpdate extends GameEvent { + + public final List attackers; + public final List blockers; + + public GameEventCombatUpdate(List attackers, List blockers) { + this.attackers = attackers; + this.blockers = blockers; + } + + @Override + public T visit(IGameEventVisitor visitor) { + return visitor.visit(this); + } + +} diff --git a/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java b/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java index d78e2c4fc66..2ded38b9cc4 100644 --- a/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java +++ b/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java @@ -21,6 +21,7 @@ public interface IGameEventVisitor { T visit(GameEventCardCounters event); T visit(GameEventCombatChanged event); T visit(GameEventCombatEnded event); + T visit(GameEventCombatUpdate event); T visit(GameEventGameFinished event); T visit(GameEventGameOutcome event); T visit(GameEventFlipCoin event); @@ -69,6 +70,7 @@ public interface IGameEventVisitor { public T visit(GameEventCardPhased event) { return null; } public T visit(GameEventCombatChanged event) { return null; } public T visit(GameEventCombatEnded event) { return null; } + public T visit(GameEventCombatUpdate event) { return null; } public T visit(GameEventGameFinished event) { return null; } public T visit(GameEventGameOutcome event) { return null; } public T visit(GameEventFlipCoin event) { return null; } diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index d5df5b8aef8..ac3f6a17347 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -179,6 +179,7 @@ public enum TrackableProperty { BandsWithBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze), AttackersWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze), BandsWithPlannedBlockers(TrackableTypes.GenericMapType, FreezeMode.IgnoresFreeze), + CombatView(TrackableTypes.CombatViewType, FreezeMode.IgnoresFreeze), //Game Players(TrackableTypes.PlayerViewCollectionType), @@ -219,6 +220,10 @@ public enum TrackableProperty { return freezeMode; } + public TrackableType getType() { + return type; + } + @SuppressWarnings("unchecked") public void updateObjLookup(Tracker tracker, T newObj) { ((TrackableType)type).updateObjLookup(tracker, newObj); diff --git a/forge-game/src/main/java/forge/trackable/TrackableTypes.java b/forge-game/src/main/java/forge/trackable/TrackableTypes.java index 0dce88f71e5..c9aeae9ca53 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableTypes.java +++ b/forge-game/src/main/java/forge/trackable/TrackableTypes.java @@ -17,6 +17,7 @@ import forge.game.GameEntityView; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.game.card.CounterType; +import forge.game.combat.CombatView; import forge.game.keyword.KeywordCollection.KeywordCollectionView; import forge.game.player.PlayerView; import forge.game.spellability.StackItemView; @@ -104,10 +105,16 @@ public class TrackableTypes { T newObj = newCollection.get(i); if (newObj != null) { T existingObj = from.getTracker().getObj(itemType, newObj.getId()); - if (existingObj != null) { //if object exists already, update its changed properties - existingObj.copyChangedProps(newObj); - newCollection.remove(i); - newCollection.add(i, existingObj); + if (existingObj != null) { //fix cards with alternate state/ manifest/ morph/ adventure etc... + if (prop.getType() == TrackableTypes.CardViewCollectionType || + prop.getType() == TrackableTypes.StackItemViewListType) { + newCollection.remove(i); + newCollection.add(i, newObj); + } else { //if object exists already, update its changed properties + existingObj.copyChangedProps(newObj); + newCollection.remove(i); + newCollection.add(i, existingObj); + } } else { //if object is new, cache in object lookup from.getTracker().putObj(itemType, newObj.getId(), newObj); @@ -626,4 +633,26 @@ public class TrackableTypes { public void serialize(TrackableSerializer ts, Map value) { } }; + public static final TrackableObjectType CombatViewType = new TrackableObjectType() { + @Override + protected CombatView getDefaultValue() { + return null; + } + + @Override + protected CombatView deserialize(TrackableDeserializer td, CombatView oldValue) { + oldValue.deserialize(td); //TODO handle old value being null or changing to null + return oldValue; + } + + @Override + protected void serialize(TrackableSerializer ts, CombatView value) { + if (value == null) { + ts.write(-1); + } + else { + value.serialize(ts); + } + } + }; } diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index ef88c70b228..dce00b61f56 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -274,8 +274,8 @@ public class Forge implements ApplicationListener { @Override public void run(Boolean result) { if (result) { - Dscreens.removeFirst(); - setCurrentScreen(Dscreens.getFirst()); + Dscreens.pollFirst(); + setCurrentScreen(Dscreens.peekFirst()); } } }); diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index 618127e4bd8..99a0e22801c 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -119,10 +119,7 @@ public class MatchController extends AbstractGuiGame { public void refreshField() { if(!GuiBase.isNetworkplay()) return; - if(getGameView().getPhase() == null) - return; - if (getGameView().getPhase().phaseforUpdateField()) - refreshCardDetails(null); + refreshCardDetails(null); } public boolean hotSeatMode() { diff --git a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java index fca98ffe702..f3f3f0a1b72 100644 --- a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java +++ b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java @@ -361,6 +361,21 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return processCards(event.blockers, cardsUpdate); } + @Override + public Void visit(final GameEventCombatUpdate event) { + if (!GuiBase.isNetworkplay()) + return null; //not needed if single player only... + + final CardCollection cards = new CardCollection(); + cards.addAll(event.attackers); + cards.addAll(event.blockers); + + refreshFieldUpdate = true; + + processCards(cards, cardsRefreshDetails); + return processCards(cards, cardsUpdate); + } + @Override public Void visit(final GameEventCardChangeZone event) { if(GuiBase.getInterface().isLibgdxPort()) { @@ -373,6 +388,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { @Override public Void visit(final GameEventCardStatsChanged event) { + refreshFieldUpdate = true; processCards(event.cards, cardsRefreshDetails); return processCards(event.cards, cardsUpdate); } @@ -397,6 +413,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { @Override public Void visit(final GameEventTokenStateUpdate event) { + refreshFieldUpdate = true; processCards(event.cards, cardsRefreshDetails); return processCards(event.cards, cardsUpdate); } diff --git a/forge-gui/src/main/java/forge/match/input/InputAttack.java b/forge-gui/src/main/java/forge/match/input/InputAttack.java index 88747ee34de..956b94f5c31 100644 --- a/forge-gui/src/main/java/forge/match/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/match/input/InputAttack.java @@ -26,6 +26,7 @@ import forge.game.card.CardPredicates.Presets; import forge.game.combat.AttackingBand; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; +import forge.game.event.GameEventCombatUpdate; import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.player.PlayerView; @@ -335,6 +336,9 @@ public class InputAttack extends InputSyncronizedBase { updatePrompt(); + if (combat != null) + getController().getGame().fireEvent(new GameEventCombatUpdate(combat.getAttackers(), combat.getAllBlockers())); + getController().getGui().showCombat(); // redraw sword icons } } diff --git a/forge-gui/src/main/java/forge/match/input/InputBlock.java b/forge-gui/src/main/java/forge/match/input/InputBlock.java index 0cee2f4cb3c..b3deff42243 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBlock.java +++ b/forge-gui/src/main/java/forge/match/input/InputBlock.java @@ -26,6 +26,7 @@ import forge.game.card.CardView; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.event.GameEventCombatChanged; +import forge.game.event.GameEventCombatUpdate; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.player.PlayerControllerHuman; @@ -89,6 +90,9 @@ public class InputBlock extends InputSyncronizedBase { showMessage(message); } + if (combat != null) + getController().getGame().fireEvent(new GameEventCombatUpdate(combat.getAttackers(), combat.getAllBlockers())); + getController().getGui().showCombat(); }