diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 20900adcb56..b16504526ba 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -17,39 +17,11 @@ */ package forge.screens.match; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.event.KeyEvent; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicReference; - -import javax.swing.JMenu; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; - import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; - -import forge.FThreads; -import forge.GuiBase; -import forge.ImageCache; -import forge.LobbyPlayer; -import forge.Singletons; -import forge.StaticData; +import com.google.common.collect.Lists; +import forge.*; import forge.assets.FSkinProp; import forge.card.CardStateName; import forge.control.KeyboardShortcuts; @@ -71,51 +43,26 @@ import forge.game.phase.PhaseType; import forge.game.player.DelayedReveal; import forge.game.player.IHasIcon; import forge.game.player.PlayerView; -import forge.game.spellability.SpellAbility; -import forge.game.spellability.SpellAbilityStackInstance; -import forge.game.spellability.SpellAbilityView; -import forge.game.spellability.StackItemView; -import forge.game.spellability.TargetChoices; +import forge.game.spellability.*; import forge.game.zone.ZoneType; -import forge.gui.FNetOverlay; -import forge.gui.GuiChoose; -import forge.gui.GuiDialog; -import forge.gui.GuiUtils; -import forge.gui.SOverlayUtils; -import forge.gui.framework.DragCell; -import forge.gui.framework.EDocID; -import forge.gui.framework.FScreen; -import forge.gui.framework.ICDoc; -import forge.gui.framework.IVDoc; -import forge.gui.framework.SDisplayUtil; -import forge.gui.framework.SLayoutIO; -import forge.gui.framework.VEmptyDoc; +import forge.gui.*; +import forge.gui.framework.*; import forge.item.InventoryItem; import forge.item.PaperCard; import forge.match.AbstractGuiGame; import forge.menus.IMenuProvider; import forge.model.FModel; import forge.player.PlayerZoneUpdate; +import forge.player.PlayerZoneUpdates; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; -import forge.screens.match.controllers.CAntes; -import forge.screens.match.controllers.CCombat; -import forge.screens.match.controllers.CDetailPicture; -import forge.screens.match.controllers.CDev; -import forge.screens.match.controllers.CDock; -import forge.screens.match.controllers.CLog; -import forge.screens.match.controllers.CPrompt; -import forge.screens.match.controllers.CStack; +import forge.screens.match.controllers.*; import forge.screens.match.menus.CMatchUIMenus; import forge.screens.match.views.VField; import forge.screens.match.views.VHand; -import forge.toolbox.FButton; -import forge.toolbox.FLabel; -import forge.toolbox.FOptionPane; -import forge.toolbox.FSkin; +import forge.toolbox.*; import forge.toolbox.FSkin.SkinImage; -import forge.toolbox.FTextArea; import forge.toolbox.imaging.FImagePanel; import forge.toolbox.imaging.FImagePanel.AutoSizeImageMode; import forge.toolbox.imaging.FImageUtil; @@ -123,15 +70,26 @@ import forge.toolbox.special.PhaseIndicator; import forge.toolbox.special.PhaseLabel; import forge.trackable.TrackableCollection; import forge.util.ITriggerEvent; +import forge.util.Localizer; import forge.util.collect.FCollection; import forge.util.collect.FCollectionView; import forge.util.gui.SOptionPane; -import forge.util.Localizer; import forge.view.FView; import forge.view.arcane.CardPanel; import forge.view.arcane.FloatingZone; import net.miginfocom.swing.MigLayout; +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicReference; + /** * Constructs instance of match UI controller, used as a single point of * top-level control for child UIs. Tasks targeting the view of individual @@ -459,6 +417,8 @@ public final class CMatchUI @Override public Iterable tempShowZones(final PlayerView controller, final Iterable zonesToUpdate) { + List updatedPlayerZones = Lists.newArrayList(); + for (final PlayerZoneUpdate update : zonesToUpdate) { final PlayerView player = update.getPlayer(); for (final ZoneType zone : update.getZones()) { @@ -467,7 +427,9 @@ public final class CMatchUI break; case Hand: // controller hand always shown if (controller != player) { - FloatingZone.show(this,player,zone); + if (FloatingZone.show(this,player,zone)) { + updatedPlayerZones.add(update); + } } break; case Library: @@ -475,14 +437,16 @@ public final class CMatchUI case Exile: case Flashback: case Command: - FloatingZone.show(this,player,zone); + if (FloatingZone.show(this,player,zone)) { + updatedPlayerZones.add(update); + } break; default: break; } } } - return zonesToUpdate; //pfps should return only the newly shown zones + return updatedPlayerZones; } @Override @@ -1086,21 +1050,30 @@ public final class CMatchUI } @Override - public boolean openZones(final Collection zones, final Map players) { - if (zones.size() == 1) { - switch (zones.iterator().next()) { - case Battlefield: - case Hand: - return true; //don't actually need to open anything, but indicate that zone can be opened - default: - return false; + public PlayerZoneUpdates openZones(PlayerView controller, final Collection zones, final Map playersWithTargetables) { + final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); + for (final PlayerView view : playersWithTargetables.keySet()) { + for(final ZoneType zone : zones) { + if (zone.equals(ZoneType.Battlefield) || zone.equals(ZoneType.Hand)) { + continue; + } + + if (zone.equals(ZoneType.Stack)) { + // TODO: Remove this if we have ever have a Stack zone that's displayable for Counters + continue; + } + + zonesToUpdate.add(new PlayerZoneUpdate(view, zone)); } } - return false; + + tempShowZones(controller, zonesToUpdate); + return zonesToUpdate; } @Override - public void restoreOldZones(final Map playersToRestoreZonesFor) { + public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) { + hideZones(playerView, playerZoneUpdates); } @Override diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java index d686c6bb341..c5282b053b5 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java @@ -17,18 +17,6 @@ */ package forge.view.arcane; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.ScrollPaneConstants; -import javax.swing.Timer; - import forge.Singletons; import forge.game.card.CardView; import forge.gui.framework.SDisplayUtil; @@ -39,10 +27,19 @@ import forge.screens.match.CMatchUI; import forge.toolbox.FMouseAdapter; import forge.toolbox.FScrollPane; import forge.toolbox.MouseTriggerEvent; -//import forge.util.collect.FCollectionView; import forge.view.FDialog; import forge.view.FFrame; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +//import forge.util.collect.FCollectionView; + // show some cards in a new window public abstract class FloatingCardArea extends CardArea { @@ -67,18 +64,20 @@ public abstract class FloatingCardArea extends CardArea { getWindow().setFocusableWindowState(false); // should probably do this earlier getWindow().setVisible(true); } + protected void hideWindow() { onShow(); getWindow().setFocusableWindowState(false); // should probably do this earlier getWindow().setVisible(false); - getWindow().dispose(); //pfps so that old content does not show up + getWindow().dispose(); //pfps so that old content does not show up } + protected void showOrHideWindow() { - if (getWindow().isVisible()) { - hideWindow(); - } else { - showWindow(); - } + if (getWindow().isVisible()) { + hideWindow(); + } else { + showWindow(); + } } protected void onShow() { if (!hasBeenShown) { @@ -98,24 +97,31 @@ public abstract class FloatingCardArea extends CardArea { if (hasBeenShown || locLoaded) { return; } super.setLocationRelativeTo(c); } + @Override public void setVisible(boolean b0) { - if (isVisible() == b0) { return; } + if (isVisible() == b0) { + return; + } if (!b0 && hasBeenShown && locPref != null) { //update preference before hiding window, as otherwise its location will be 0,0 prefs.setPref(locPref, getX() + COORD_DELIM + getY() + COORD_DELIM + - getWidth() + COORD_DELIM + getHeight()); + getWidth() + COORD_DELIM + getHeight()); //don't call prefs.save(), instead allowing them to be saved when match ends } if (b0) { - doRefresh(); // force a refresh before showing to pick up any changes when hidden + doRefresh(); // force a refresh before showing to pick up any changes when hidden hasBeenShown = true; - } + } super.setVisible(b0); } }; + public boolean isVisible() { + return window.isVisible(); + } + protected FDialog getWindow() { return window; } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingZone.java b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingZone.java index 4dba33b85f2..8efeceef05f 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingZone.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingZone.java @@ -6,38 +6,37 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package forge.view.arcane; -import java.util.HashMap; -import java.util.Map; -import java.util.Collections; -import java.util.Comparator; - -import java.awt.event.MouseEvent; -import javax.swing.ScrollPaneConstants; -import javax.swing.WindowConstants; - +import forge.FThreads; import forge.assets.FSkinProp; import forge.game.card.CardView; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; import forge.properties.ForgePreferences.FPref; import forge.screens.match.CMatchUI; -import forge.toolbox.FScrollPane; import forge.toolbox.FMouseAdapter; +import forge.toolbox.FScrollPane; import forge.toolbox.FSkin; import forge.util.Lang; import forge.util.collect.FCollection; +import javax.swing.*; +import java.awt.event.MouseEvent; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + public class FloatingZone extends FloatingCardArea { private static final long serialVersionUID = 1927906492186378596L; @@ -46,18 +45,44 @@ public class FloatingZone extends FloatingCardArea { private static int getKey(final PlayerView player, final ZoneType zone) { return 40 * player.getId() + zone.hashCode(); } + public static void showOrHide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { final FloatingZone cardArea = _init(matchUI, player, zone); cardArea.showOrHideWindow(); } - public static void show(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { + + public static boolean show(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { final FloatingZone cardArea = _init(matchUI, player, zone); - cardArea.showWindow(); + + if (cardArea.isVisible()) { + return false; + } + + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override public void run() { + cardArea.showWindow(); + } + }); + + return true; } - public static void hide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { + + public static boolean hide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { final FloatingZone cardArea = _init(matchUI, player, zone); - cardArea.hideWindow(); + + if (!cardArea.isVisible()) { + return false; + } + + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override public void run() { + cardArea.hideWindow(); + } + }); + + return true; } + private static FloatingZone _init(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { final int key = getKey(player, zone); FloatingZone cardArea = floatingAreas.get(key); @@ -69,10 +94,12 @@ public class FloatingZone extends FloatingCardArea { } return cardArea; } + public static CardPanel getCardPanel(final CMatchUI matchUI, final CardView card) { final FloatingZone window = _init(matchUI, card.getController(), card.getZone()); return window.getCardPanel(card.getId()); } + public static void refresh(final PlayerView player, final ZoneType zone) { FloatingZone cardArea = floatingAreas.get(getKey(player, zone)); if (cardArea != null) { @@ -82,21 +109,23 @@ public class FloatingZone extends FloatingCardArea { //refresh flashback zone when graveyard, library, or exile zones updated switch (zone) { - case Graveyard: - case Library: - case Exile: - refresh(player, ZoneType.Flashback); - break; - default: - break; + case Graveyard: + case Library: + case Exile: + refresh(player, ZoneType.Flashback); + break; + default: + break; } } + public static void closeAll() { for (final FloatingZone cardArea : floatingAreas.values()) { cardArea.window.setVisible(false); } floatingAreas.clear(); } + public static void refreshAll() { for (final FloatingZone cardArea : floatingAreas.values()) { cardArea.refresh(); @@ -110,23 +139,23 @@ public class FloatingZone extends FloatingCardArea { protected FCollection cardList; private final Comparator comp = new Comparator() { - @Override - public int compare(CardView lhs, CardView rhs) { - if ( !getMatchUI().mayView(lhs) ) { - return ( getMatchUI().mayView(rhs) ) ? 1 : 0 ; - } else if ( !getMatchUI().mayView(rhs) ) { - return -1; - } else { - return lhs.getName().compareTo(rhs.getName()); - } - } - }; + @Override + public int compare(CardView lhs, CardView rhs) { + if (!getMatchUI().mayView(lhs)) { + return (getMatchUI().mayView(rhs)) ? 1 : 0; + } else if (!getMatchUI().mayView(rhs)) { + return -1; + } else { + return lhs.getName().compareTo(rhs.getName()); + } + } + }; protected Iterable getCards() { Iterable zoneCards = player.getCards(zone); - if ( zoneCards != null ) { + if (zoneCards != null) { cardList = new FCollection<>(zoneCards); - if ( sortedByName ) { + if (sortedByName) { Collections.sort(cardList, comp); } return cardList; @@ -138,28 +167,28 @@ public class FloatingZone extends FloatingCardArea { private FloatingZone(final CMatchUI matchUI, final PlayerView player0, final ZoneType zone0) { super(matchUI, new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)); window.add(getScrollPane(), "grow, push"); - window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); //pfps so that old content does not reappear? + window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); //pfps so that old content does not reappear? getScrollPane().setViewportView(this); setOpaque(false); switch (zone0) { - case Exile: - window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_EXILE)); - break; - case Graveyard: - window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_GRAVEYARD)); - break; - case Hand: - window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_HAND)); - break; - case Library: - window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_LIBRARY)); - break; - case Flashback: - window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_FLASHBACK)); - break; - default: - locPref = null; - break; + case Exile: + window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_EXILE)); + break; + case Graveyard: + window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_GRAVEYARD)); + break; + case Hand: + window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_HAND)); + break; + case Library: + window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_LIBRARY)); + break; + case Flashback: + window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_FLASHBACK)); + break; + default: + locPref = null; + break; } zone = zone0; setPlayer(player0); @@ -167,19 +196,20 @@ public class FloatingZone extends FloatingCardArea { } private void toggleSorted() { - sortedByName = !sortedByName; - setTitle(); - refresh(); - // revalidation does not appear to be necessary here - getWindow().repaint(); + sortedByName = !sortedByName; + setTitle(); + refresh(); + // revalidation does not appear to be necessary here + getWindow().repaint(); } @Override protected void onShow() { - super.onShow(); + super.onShow(); if (!hasBeenShown) { getWindow().getTitleBar().addMouseListener(new FMouseAdapter() { - @Override public final void onRightClick(final MouseEvent e) { + @Override + public final void onRightClick(final MouseEvent e) { toggleSorted(); } }); @@ -188,34 +218,36 @@ public class FloatingZone extends FloatingCardArea { private void setTitle() { title = Lang.getPossessedObject(player.getName(), zone.name()) + " (%d)" + - ( sortedByName ? " - sorted by name (right click in title to not sort)" : " (right click in title to sort)" ) ; - } + (sortedByName ? " - sorted by name (right click in title to not sort)" : " (right click in title to sort)"); + } private void setPlayer(PlayerView player0) { - if (player == player0) { return; } + if (player == player0) { + return; + } player = player0; - setTitle(); + setTitle(); boolean isAi = player0.isAI(); switch (zone) { - case Exile: - locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE; - break; - case Graveyard: - locPref = isAi ? FPref.ZONE_LOC_AI_GRAVEYARD : FPref.ZONE_LOC_HUMAN_GRAVEYARD; - break; - case Hand: - locPref = isAi ? FPref.ZONE_LOC_AI_HAND : FPref.ZONE_LOC_HUMAN_HAND; - break; - case Library: - locPref = isAi ? FPref.ZONE_LOC_AI_LIBRARY : FPref.ZONE_LOC_HUMAN_LIBRARY; - break; - case Flashback: - locPref = isAi ? FPref.ZONE_LOC_AI_FLASHBACK : FPref.ZONE_LOC_HUMAN_FLASHBACK; - break; - default: - locPref = null; - break; + case Exile: + locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE; + break; + case Graveyard: + locPref = isAi ? FPref.ZONE_LOC_AI_GRAVEYARD : FPref.ZONE_LOC_HUMAN_GRAVEYARD; + break; + case Hand: + locPref = isAi ? FPref.ZONE_LOC_AI_HAND : FPref.ZONE_LOC_HUMAN_HAND; + break; + case Library: + locPref = isAi ? FPref.ZONE_LOC_AI_LIBRARY : FPref.ZONE_LOC_HUMAN_LIBRARY; + break; + case Flashback: + locPref = isAi ? FPref.ZONE_LOC_AI_FLASHBACK : FPref.ZONE_LOC_HUMAN_FLASHBACK; + break; + default: + locPref = null; + break; } } diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiGame.java b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java index aac6d6aaf34..997c5e7b09a 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiGame.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java @@ -1,11 +1,6 @@ package forge.interfaces; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.google.common.base.Function; - import forge.LobbyPlayer; import forge.assets.FSkinProp; import forge.deck.CardPool; @@ -22,9 +17,14 @@ import forge.game.spellability.SpellAbilityView; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.player.PlayerZoneUpdate; +import forge.player.PlayerZoneUpdates; import forge.trackable.TrackableCollection; import forge.util.ITriggerEvent; +import java.util.Collection; +import java.util.List; +import java.util.Map; + public interface IGuiGame { void setGameView(GameView gameView); GameView getGameView(); @@ -107,7 +107,6 @@ public interface IGuiGame { * @return null if choices is missing, empty, or if the users' choices are * empty; otherwise, returns the first item in the List returned by * getChoices. - * @see #getChoices(String, int, int, Object...) */ T oneOrNone(String message, List choices); @@ -158,8 +157,8 @@ public interface IGuiGame { void setCard(CardView card); void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi); - boolean openZones(Collection zones, Map players); - void restoreOldZones(Map playersToRestoreZonesFor); + PlayerZoneUpdates openZones(PlayerView controller, Collection zones, Map players); + void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates); void setHighlighted(PlayerView pv, boolean b); void setUsedToPay(CardView card, boolean value); void setSelectables(final Iterable cards); diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java index fc8b962b19c..ab34c9f6abd 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java @@ -1,23 +1,22 @@ package forge.match.input; -import java.util.Collection; -import java.util.List; -import java.util.ArrayList; - +import forge.FThreads; import forge.game.GameEntity; import forge.game.card.Card; import forge.game.card.CardView; - import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.Zone; import forge.player.PlayerControllerHuman; -import forge.util.collect.FCollection; -import forge.util.collect.FCollectionView; -import forge.util.ITriggerEvent; import forge.player.PlayerZoneUpdate; import forge.player.PlayerZoneUpdates; -import forge.game.zone.Zone; -import forge.FThreads; +import forge.util.ITriggerEvent; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; public class InputSelectEntitiesFromList extends InputSelectManyBase { private static final long serialVersionUID = -6609493252672573139L; @@ -31,31 +30,32 @@ public class InputSelectEntitiesFromList extends InputSele } public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView validChoices0, final SpellAbility sa0) { - super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()),sa0); + super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()), sa0); validChoices = validChoices0; if (min > validChoices.size()) { // pfps does this really do anything useful?? System.out.println(String.format("Trying to choose at least %d things from a list with only %d things!", min, validChoices.size())); } - ArrayList vCards = new ArrayList<>(); - for ( T c : validChoices0 ) { - if ( c instanceof Card ) { - vCards.add(((Card)c).getView()) ; - } - } - getController().getGui().setSelectables(vCards); - final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); - for (final GameEntity c : validChoices) { - final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null ; - if ( cz != null ) { - zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(),cz.getZoneType())); - } - } - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override public void run() { - getController().getGui().updateZones(zonesToUpdate); - zonesShown = getController().getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate); + ArrayList vCards = new ArrayList<>(); + for (T c : validChoices0) { + if (c instanceof Card) { + vCards.add(((Card) c).getView()); } - }); + } + getController().getGui().setSelectables(vCards); + final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); + for (final GameEntity c : validChoices) { + final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null; + if (cz != null) { + zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(), cz.getZoneType())); + } + } + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override + public void run() { + getController().getGui().updateZones(zonesToUpdate); + zonesShown = getController().getGui().tempShowZones(controller.getPlayer().getView(), zonesToUpdate); + } + }); } @Override diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java index d67b78b4698..547b185b681 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java @@ -1,13 +1,7 @@ package forge.match.input; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - import com.google.common.collect.ImmutableList; - +import forge.FThreads; import forge.game.GameEntity; import forge.game.GameObject; import forge.game.ability.ApiType; @@ -18,13 +12,18 @@ import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.model.FModel; import forge.player.PlayerControllerHuman; +import forge.player.PlayerZoneUpdate; +import forge.player.PlayerZoneUpdates; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.util.ITriggerEvent; import forge.util.TextUtil; -import forge.player.PlayerZoneUpdate; -import forge.player.PlayerZoneUpdates; -import forge.FThreads; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; public final class InputSelectTargets extends InputSyncronizedBase { private final List choices; @@ -47,16 +46,17 @@ public final class InputSelectTargets extends InputSyncronizedBase { this.tgt = sa.getTargetRestrictions(); this.sa = sa; this.mandatory = mandatory; - controller.getGui().setSelectables(CardView.getCollection(choices)); - final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); - for (final Card c : choices) { - zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(),c.getZone().getZoneType())); - } - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override public void run() { - controller.getGui().updateZones(zonesToUpdate); + controller.getGui().setSelectables(CardView.getCollection(choices)); + final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); + for (final Card c : choices) { + zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(), c.getZone().getZoneType())); + } + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override + public void run() { + controller.getGui().updateZones(zonesToUpdate); } - }); + }); } @Override diff --git a/forge-gui/src/main/java/forge/net/ProtocolMethod.java b/forge-gui/src/main/java/forge/net/ProtocolMethod.java index 254ac09a3c5..4497b5cf0f9 100644 --- a/forge-gui/src/main/java/forge/net/ProtocolMethod.java +++ b/forge-gui/src/main/java/forge/net/ProtocolMethod.java @@ -1,14 +1,6 @@ package forge.net; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.List; -import java.util.Map; - import com.google.common.base.Function; - import forge.GuiBase; import forge.assets.FSkinProp; import forge.deck.CardPool; @@ -22,11 +14,19 @@ import forge.game.spellability.SpellAbilityView; import forge.interfaces.IGameController; import forge.interfaces.IGuiGame; import forge.match.NextGameDecision; +import forge.player.PlayerZoneUpdates; import forge.trackable.TrackableCollection; import forge.util.ITriggerEvent; import forge.util.ReflectionUtil; import org.apache.commons.lang3.SerializationUtils; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.List; +import java.util.Map; + /** * The methods that can be sent through this protocol. */ @@ -75,8 +75,8 @@ public enum ProtocolMethod { clearSelectables (Mode.SERVER), refreshField (Mode.SERVER), // TODO case "setPlayerAvatar": - openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), - restoreOldZones (Mode.SERVER, Void.TYPE, Map/*PlayerView,Object*/.class), + openZones (Mode.SERVER, PlayerZoneUpdates.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), + restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class), isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class), setRememberedActions(Mode.SERVER, Void.TYPE), nextRememberedAction(Mode.SERVER, Void.TYPE), diff --git a/forge-gui/src/main/java/forge/net/server/NetGuiGame.java b/forge-gui/src/main/java/forge/net/server/NetGuiGame.java index 7601297f2e6..33e6f727b07 100644 --- a/forge-gui/src/main/java/forge/net/server/NetGuiGame.java +++ b/forge-gui/src/main/java/forge/net/server/NetGuiGame.java @@ -1,11 +1,6 @@ package forge.net.server; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.google.common.base.Function; - import forge.LobbyPlayer; import forge.assets.FSkinProp; import forge.deck.CardPool; @@ -23,9 +18,14 @@ import forge.match.AbstractGuiGame; import forge.net.GameProtocolSender; import forge.net.ProtocolMethod; import forge.player.PlayerZoneUpdate; +import forge.player.PlayerZoneUpdates; import forge.trackable.TrackableCollection; import forge.util.ITriggerEvent; +import java.util.Collection; +import java.util.List; +import java.util.Map; + public class NetGuiGame extends AbstractGuiGame { private final GameProtocolSender sender; @@ -283,14 +283,14 @@ public class NetGuiGame extends AbstractGuiGame { } @Override - public boolean openZones(final Collection zones, final Map players) { + public PlayerZoneUpdates openZones(PlayerView controller, final Collection zones, final Map players) { updateGameView(); - return sendAndWait(ProtocolMethod.openZones, zones, players); + return sendAndWait(ProtocolMethod.openZones, controller, zones, players); } @Override - public void restoreOldZones(final Map playersToRestoreZonesFor) { - send(ProtocolMethod.restoreOldZones, playersToRestoreZonesFor); + public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) { + send(ProtocolMethod.restoreOldZones, playerView, playerZoneUpdates); } @Override diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index deced7b9fb8..914f22e0916 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -100,7 +100,7 @@ public class TargetSelection { return true; } - final List zone = tgt.getZone(); + final List zones = tgt.getZone(); final boolean mandatory = tgt.getMandatory() && hasCandidates; final boolean choiceResult; @@ -110,7 +110,7 @@ public class TargetSelection { final GameObject choice = Aggregates.random(candidates); return ability.getTargets().add(choice); } - else if (zone.size() == 1 && zone.get(0) == ZoneType.Stack) { + else if (zones.size() == 1 && zones.get(0) == ZoneType.Stack) { // If Zone is Stack, the choices are handled slightly differently. // Handle everything inside function due to interaction with StackInstance return this.chooseCardFromStack(mandatory); @@ -152,12 +152,15 @@ public class TargetSelection { for (Card card : validTargets) { playersWithValidTargets.put(PlayerView.get(card.getController()), null); } - if (controller.getGui().openZones(zone, playersWithValidTargets)) { + + PlayerView playerView = controller.getLocalPlayerView(); + PlayerZoneUpdates playerZoneUpdates = controller.getGui().openZones(playerView, zones, playersWithValidTargets); + if (!zones.contains(ZoneType.Stack)) { InputSelectTargets inp = new InputSelectTargets(controller, validTargets, ability, mandatory); inp.showAndWait(); choiceResult = !inp.hasCancelled(); bTargetingDone = inp.hasPressedOk(); - controller.getGui().restoreOldZones(playersWithValidTargets); + controller.getGui().restoreOldZones(playerView, playerZoneUpdates); } else { // for every other case an all-purpose GuiChoose