Pop up other zones during targeting

This commit is contained in:
friarsol
2020-02-09 21:32:24 -05:00
parent b994bce116
commit ef0a1a843d
9 changed files with 275 additions and 262 deletions

View File

@@ -17,39 +17,11 @@
*/ */
package forge.screens.match; 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.base.Function;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import forge.FThreads; import forge.*;
import forge.GuiBase;
import forge.ImageCache;
import forge.LobbyPlayer;
import forge.Singletons;
import forge.StaticData;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.control.KeyboardShortcuts; import forge.control.KeyboardShortcuts;
@@ -71,51 +43,26 @@ import forge.game.phase.PhaseType;
import forge.game.player.DelayedReveal; import forge.game.player.DelayedReveal;
import forge.game.player.IHasIcon; import forge.game.player.IHasIcon;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.game.spellability.SpellAbility; import forge.game.spellability.*;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.SpellAbilityView;
import forge.game.spellability.StackItemView;
import forge.game.spellability.TargetChoices;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.FNetOverlay; import forge.gui.*;
import forge.gui.GuiChoose; import forge.gui.framework.*;
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.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.match.AbstractGuiGame; import forge.match.AbstractGuiGame;
import forge.menus.IMenuProvider; import forge.menus.IMenuProvider;
import forge.model.FModel; import forge.model.FModel;
import forge.player.PlayerZoneUpdate; import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.properties.ForgeConstants; import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.screens.match.controllers.CAntes; import forge.screens.match.controllers.*;
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.menus.CMatchUIMenus; import forge.screens.match.menus.CMatchUIMenus;
import forge.screens.match.views.VField; import forge.screens.match.views.VField;
import forge.screens.match.views.VHand; import forge.screens.match.views.VHand;
import forge.toolbox.FButton; import forge.toolbox.*;
import forge.toolbox.FLabel;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinImage; import forge.toolbox.FSkin.SkinImage;
import forge.toolbox.FTextArea;
import forge.toolbox.imaging.FImagePanel; import forge.toolbox.imaging.FImagePanel;
import forge.toolbox.imaging.FImagePanel.AutoSizeImageMode; import forge.toolbox.imaging.FImagePanel.AutoSizeImageMode;
import forge.toolbox.imaging.FImageUtil; import forge.toolbox.imaging.FImageUtil;
@@ -123,15 +70,26 @@ import forge.toolbox.special.PhaseIndicator;
import forge.toolbox.special.PhaseLabel; import forge.toolbox.special.PhaseLabel;
import forge.trackable.TrackableCollection; import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
import forge.util.Localizer;
import forge.util.collect.FCollection; import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
import forge.util.gui.SOptionPane; import forge.util.gui.SOptionPane;
import forge.util.Localizer;
import forge.view.FView; import forge.view.FView;
import forge.view.arcane.CardPanel; import forge.view.arcane.CardPanel;
import forge.view.arcane.FloatingZone; import forge.view.arcane.FloatingZone;
import net.miginfocom.swing.MigLayout; 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 * Constructs instance of match UI controller, used as a single point of
* top-level control for child UIs. Tasks targeting the view of individual * top-level control for child UIs. Tasks targeting the view of individual
@@ -459,6 +417,8 @@ public final class CMatchUI
@Override @Override
public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) { public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
List<PlayerZoneUpdate> updatedPlayerZones = Lists.newArrayList();
for (final PlayerZoneUpdate update : zonesToUpdate) { for (final PlayerZoneUpdate update : zonesToUpdate) {
final PlayerView player = update.getPlayer(); final PlayerView player = update.getPlayer();
for (final ZoneType zone : update.getZones()) { for (final ZoneType zone : update.getZones()) {
@@ -467,7 +427,9 @@ public final class CMatchUI
break; break;
case Hand: // controller hand always shown case Hand: // controller hand always shown
if (controller != player) { if (controller != player) {
FloatingZone.show(this,player,zone); if (FloatingZone.show(this,player,zone)) {
updatedPlayerZones.add(update);
}
} }
break; break;
case Library: case Library:
@@ -475,14 +437,16 @@ public final class CMatchUI
case Exile: case Exile:
case Flashback: case Flashback:
case Command: case Command:
FloatingZone.show(this,player,zone); if (FloatingZone.show(this,player,zone)) {
updatedPlayerZones.add(update);
}
break; break;
default: default:
break; break;
} }
} }
} }
return zonesToUpdate; //pfps should return only the newly shown zones return updatedPlayerZones;
} }
@Override @Override
@@ -1086,21 +1050,30 @@ public final class CMatchUI
} }
@Override @Override
public boolean openZones(final Collection<ZoneType> zones, final Map<PlayerView, Object> players) { public PlayerZoneUpdates openZones(PlayerView controller, final Collection<ZoneType> zones, final Map<PlayerView, Object> playersWithTargetables) {
if (zones.size() == 1) { final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
switch (zones.iterator().next()) { for (final PlayerView view : playersWithTargetables.keySet()) {
case Battlefield: for(final ZoneType zone : zones) {
case Hand: if (zone.equals(ZoneType.Battlefield) || zone.equals(ZoneType.Hand)) {
return true; //don't actually need to open anything, but indicate that zone can be opened continue;
default: }
return false;
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 @Override
public void restoreOldZones(final Map<PlayerView, Object> playersToRestoreZonesFor) { public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) {
hideZones(playerView, playerZoneUpdates);
} }
@Override @Override

View File

@@ -17,18 +17,6 @@
*/ */
package forge.view.arcane; 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.Singletons;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SDisplayUtil;
@@ -39,10 +27,19 @@ import forge.screens.match.CMatchUI;
import forge.toolbox.FMouseAdapter; import forge.toolbox.FMouseAdapter;
import forge.toolbox.FScrollPane; import forge.toolbox.FScrollPane;
import forge.toolbox.MouseTriggerEvent; import forge.toolbox.MouseTriggerEvent;
//import forge.util.collect.FCollectionView;
import forge.view.FDialog; import forge.view.FDialog;
import forge.view.FFrame; 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 // show some cards in a new window
public abstract class FloatingCardArea extends CardArea { 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().setFocusableWindowState(false); // should probably do this earlier
getWindow().setVisible(true); getWindow().setVisible(true);
} }
protected void hideWindow() { protected void hideWindow() {
onShow(); onShow();
getWindow().setFocusableWindowState(false); // should probably do this earlier getWindow().setFocusableWindowState(false); // should probably do this earlier
getWindow().setVisible(false); 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() { protected void showOrHideWindow() {
if (getWindow().isVisible()) { if (getWindow().isVisible()) {
hideWindow(); hideWindow();
} else { } else {
showWindow(); showWindow();
} }
} }
protected void onShow() { protected void onShow() {
if (!hasBeenShown) { if (!hasBeenShown) {
@@ -98,24 +97,31 @@ public abstract class FloatingCardArea extends CardArea {
if (hasBeenShown || locLoaded) { return; } if (hasBeenShown || locLoaded) { return; }
super.setLocationRelativeTo(c); super.setLocationRelativeTo(c);
} }
@Override @Override
public void setVisible(boolean b0) { public void setVisible(boolean b0) {
if (isVisible() == b0) { return; } if (isVisible() == b0) {
return;
}
if (!b0 && hasBeenShown && locPref != null) { if (!b0 && hasBeenShown && locPref != null) {
//update preference before hiding window, as otherwise its location will be 0,0 //update preference before hiding window, as otherwise its location will be 0,0
prefs.setPref(locPref, prefs.setPref(locPref,
getX() + COORD_DELIM + getY() + COORD_DELIM + 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 //don't call prefs.save(), instead allowing them to be saved when match ends
} }
if (b0) { 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; hasBeenShown = true;
} }
super.setVisible(b0); super.setVisible(b0);
} }
}; };
public boolean isVisible() {
return window.isVisible();
}
protected FDialog getWindow() { protected FDialog getWindow() {
return window; return window;
} }

View File

@@ -6,38 +6,37 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package forge.view.arcane; package forge.view.arcane;
import java.util.HashMap; import forge.FThreads;
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.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.screens.match.CMatchUI; import forge.screens.match.CMatchUI;
import forge.toolbox.FScrollPane;
import forge.toolbox.FMouseAdapter; import forge.toolbox.FMouseAdapter;
import forge.toolbox.FScrollPane;
import forge.toolbox.FSkin; import forge.toolbox.FSkin;
import forge.util.Lang; import forge.util.Lang;
import forge.util.collect.FCollection; 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 { public class FloatingZone extends FloatingCardArea {
private static final long serialVersionUID = 1927906492186378596L; 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) { private static int getKey(final PlayerView player, final ZoneType zone) {
return 40 * player.getId() + zone.hashCode(); return 40 * player.getId() + zone.hashCode();
} }
public static void showOrHide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { public static void showOrHide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) {
final FloatingZone cardArea = _init(matchUI, player, zone); final FloatingZone cardArea = _init(matchUI, player, zone);
cardArea.showOrHideWindow(); 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); 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); 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) { private static FloatingZone _init(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) {
final int key = getKey(player, zone); final int key = getKey(player, zone);
FloatingZone cardArea = floatingAreas.get(key); FloatingZone cardArea = floatingAreas.get(key);
@@ -69,10 +94,12 @@ public class FloatingZone extends FloatingCardArea {
} }
return cardArea; return cardArea;
} }
public static CardPanel getCardPanel(final CMatchUI matchUI, final CardView card) { public static CardPanel getCardPanel(final CMatchUI matchUI, final CardView card) {
final FloatingZone window = _init(matchUI, card.getController(), card.getZone()); final FloatingZone window = _init(matchUI, card.getController(), card.getZone());
return window.getCardPanel(card.getId()); return window.getCardPanel(card.getId());
} }
public static void refresh(final PlayerView player, final ZoneType zone) { public static void refresh(final PlayerView player, final ZoneType zone) {
FloatingZone cardArea = floatingAreas.get(getKey(player, zone)); FloatingZone cardArea = floatingAreas.get(getKey(player, zone));
if (cardArea != null) { if (cardArea != null) {
@@ -82,21 +109,23 @@ public class FloatingZone extends FloatingCardArea {
//refresh flashback zone when graveyard, library, or exile zones updated //refresh flashback zone when graveyard, library, or exile zones updated
switch (zone) { switch (zone) {
case Graveyard: case Graveyard:
case Library: case Library:
case Exile: case Exile:
refresh(player, ZoneType.Flashback); refresh(player, ZoneType.Flashback);
break; break;
default: default:
break; break;
} }
} }
public static void closeAll() { public static void closeAll() {
for (final FloatingZone cardArea : floatingAreas.values()) { for (final FloatingZone cardArea : floatingAreas.values()) {
cardArea.window.setVisible(false); cardArea.window.setVisible(false);
} }
floatingAreas.clear(); floatingAreas.clear();
} }
public static void refreshAll() { public static void refreshAll() {
for (final FloatingZone cardArea : floatingAreas.values()) { for (final FloatingZone cardArea : floatingAreas.values()) {
cardArea.refresh(); cardArea.refresh();
@@ -110,23 +139,23 @@ public class FloatingZone extends FloatingCardArea {
protected FCollection<CardView> cardList; protected FCollection<CardView> cardList;
private final Comparator<CardView> comp = new Comparator<CardView>() { private final Comparator<CardView> comp = new Comparator<CardView>() {
@Override @Override
public int compare(CardView lhs, CardView rhs) { public int compare(CardView lhs, CardView rhs) {
if ( !getMatchUI().mayView(lhs) ) { if (!getMatchUI().mayView(lhs)) {
return ( getMatchUI().mayView(rhs) ) ? 1 : 0 ; return (getMatchUI().mayView(rhs)) ? 1 : 0;
} else if ( !getMatchUI().mayView(rhs) ) { } else if (!getMatchUI().mayView(rhs)) {
return -1; return -1;
} else { } else {
return lhs.getName().compareTo(rhs.getName()); return lhs.getName().compareTo(rhs.getName());
} }
} }
}; };
protected Iterable<CardView> getCards() { protected Iterable<CardView> getCards() {
Iterable<CardView> zoneCards = player.getCards(zone); Iterable<CardView> zoneCards = player.getCards(zone);
if ( zoneCards != null ) { if (zoneCards != null) {
cardList = new FCollection<>(zoneCards); cardList = new FCollection<>(zoneCards);
if ( sortedByName ) { if (sortedByName) {
Collections.sort(cardList, comp); Collections.sort(cardList, comp);
} }
return cardList; return cardList;
@@ -138,28 +167,28 @@ public class FloatingZone extends FloatingCardArea {
private FloatingZone(final CMatchUI matchUI, final PlayerView player0, final ZoneType zone0) { 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)); super(matchUI, new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
window.add(getScrollPane(), "grow, push"); 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); getScrollPane().setViewportView(this);
setOpaque(false); setOpaque(false);
switch (zone0) { switch (zone0) {
case Exile: case Exile:
window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_EXILE)); window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_EXILE));
break; break;
case Graveyard: case Graveyard:
window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_GRAVEYARD)); window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_GRAVEYARD));
break; break;
case Hand: case Hand:
window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_HAND)); window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_HAND));
break; break;
case Library: case Library:
window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_LIBRARY)); window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_LIBRARY));
break; break;
case Flashback: case Flashback:
window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_FLASHBACK)); window.setIconImage(FSkin.getImage(FSkinProp.IMG_ZONE_FLASHBACK));
break; break;
default: default:
locPref = null; locPref = null;
break; break;
} }
zone = zone0; zone = zone0;
setPlayer(player0); setPlayer(player0);
@@ -167,19 +196,20 @@ public class FloatingZone extends FloatingCardArea {
} }
private void toggleSorted() { private void toggleSorted() {
sortedByName = !sortedByName; sortedByName = !sortedByName;
setTitle(); setTitle();
refresh(); refresh();
// revalidation does not appear to be necessary here // revalidation does not appear to be necessary here
getWindow().repaint(); getWindow().repaint();
} }
@Override @Override
protected void onShow() { protected void onShow() {
super.onShow(); super.onShow();
if (!hasBeenShown) { if (!hasBeenShown) {
getWindow().getTitleBar().addMouseListener(new FMouseAdapter() { getWindow().getTitleBar().addMouseListener(new FMouseAdapter() {
@Override public final void onRightClick(final MouseEvent e) { @Override
public final void onRightClick(final MouseEvent e) {
toggleSorted(); toggleSorted();
} }
}); });
@@ -188,34 +218,36 @@ public class FloatingZone extends FloatingCardArea {
private void setTitle() { private void setTitle() {
title = Lang.getPossessedObject(player.getName(), zone.name()) + " (%d)" + 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) { private void setPlayer(PlayerView player0) {
if (player == player0) { return; } if (player == player0) {
return;
}
player = player0; player = player0;
setTitle(); setTitle();
boolean isAi = player0.isAI(); boolean isAi = player0.isAI();
switch (zone) { switch (zone) {
case Exile: case Exile:
locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE; locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE;
break; break;
case Graveyard: case Graveyard:
locPref = isAi ? FPref.ZONE_LOC_AI_GRAVEYARD : FPref.ZONE_LOC_HUMAN_GRAVEYARD; locPref = isAi ? FPref.ZONE_LOC_AI_GRAVEYARD : FPref.ZONE_LOC_HUMAN_GRAVEYARD;
break; break;
case Hand: case Hand:
locPref = isAi ? FPref.ZONE_LOC_AI_HAND : FPref.ZONE_LOC_HUMAN_HAND; locPref = isAi ? FPref.ZONE_LOC_AI_HAND : FPref.ZONE_LOC_HUMAN_HAND;
break; break;
case Library: case Library:
locPref = isAi ? FPref.ZONE_LOC_AI_LIBRARY : FPref.ZONE_LOC_HUMAN_LIBRARY; locPref = isAi ? FPref.ZONE_LOC_AI_LIBRARY : FPref.ZONE_LOC_HUMAN_LIBRARY;
break; break;
case Flashback: case Flashback:
locPref = isAi ? FPref.ZONE_LOC_AI_FLASHBACK : FPref.ZONE_LOC_HUMAN_FLASHBACK; locPref = isAi ? FPref.ZONE_LOC_AI_FLASHBACK : FPref.ZONE_LOC_HUMAN_FLASHBACK;
break; break;
default: default:
locPref = null; locPref = null;
break; break;
} }
} }

View File

@@ -1,11 +1,6 @@
package forge.interfaces; package forge.interfaces;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function; import com.google.common.base.Function;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.deck.CardPool; import forge.deck.CardPool;
@@ -22,9 +17,14 @@ import forge.game.spellability.SpellAbilityView;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.player.PlayerZoneUpdate; import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection; import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface IGuiGame { public interface IGuiGame {
void setGameView(GameView gameView); void setGameView(GameView gameView);
GameView getGameView(); GameView getGameView();
@@ -107,7 +107,6 @@ public interface IGuiGame {
* @return null if choices is missing, empty, or if the users' choices are * @return null if choices is missing, empty, or if the users' choices are
* empty; otherwise, returns the first item in the List returned by * empty; otherwise, returns the first item in the List returned by
* getChoices. * getChoices.
* @see #getChoices(String, int, int, Object...)
*/ */
<T> T oneOrNone(String message, List<T> choices); <T> T oneOrNone(String message, List<T> choices);
@@ -158,8 +157,8 @@ public interface IGuiGame {
void setCard(CardView card); void setCard(CardView card);
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi); void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players); PlayerZoneUpdates openZones(PlayerView controller, Collection<ZoneType> zones, Map<PlayerView, Object> players);
void restoreOldZones(Map<PlayerView, Object> playersToRestoreZonesFor); void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates);
void setHighlighted(PlayerView pv, boolean b); void setHighlighted(PlayerView pv, boolean b);
void setUsedToPay(CardView card, boolean value); void setUsedToPay(CardView card, boolean value);
void setSelectables(final Iterable<CardView> cards); void setSelectables(final Iterable<CardView> cards);

View File

@@ -1,23 +1,22 @@
package forge.match.input; package forge.match.input;
import java.util.Collection; import forge.FThreads;
import java.util.List;
import java.util.ArrayList;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.Zone;
import forge.player.PlayerControllerHuman; 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.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates; import forge.player.PlayerZoneUpdates;
import forge.game.zone.Zone; import forge.util.ITriggerEvent;
import forge.FThreads; 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<T extends GameEntity> extends InputSelectManyBase<T> { public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSelectManyBase<T> {
private static final long serialVersionUID = -6609493252672573139L; private static final long serialVersionUID = -6609493252672573139L;
@@ -31,31 +30,32 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
} }
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0, final SpellAbility sa0) { public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> 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; validChoices = validChoices0;
if (min > validChoices.size()) { // pfps does this really do anything useful?? 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())); System.out.println(String.format("Trying to choose at least %d things from a list with only %d things!", min, validChoices.size()));
} }
ArrayList<CardView> vCards = new ArrayList<>(); ArrayList<CardView> vCards = new ArrayList<>();
for ( T c : validChoices0 ) { for (T c : validChoices0) {
if ( c instanceof Card ) { if (c instanceof Card) {
vCards.add(((Card)c).getView()) ; 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);
} }
}); }
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 @Override

View File

@@ -1,13 +1,7 @@
package forge.match.input; 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 com.google.common.collect.ImmutableList;
import forge.FThreads;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.GameObject; import forge.game.GameObject;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
@@ -18,13 +12,18 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions; import forge.game.spellability.TargetRestrictions;
import forge.model.FModel; import forge.model.FModel;
import forge.player.PlayerControllerHuman; import forge.player.PlayerControllerHuman;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.properties.ForgeConstants; import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
import forge.util.TextUtil; import forge.util.TextUtil;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates; import java.util.ArrayList;
import forge.FThreads; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public final class InputSelectTargets extends InputSyncronizedBase { public final class InputSelectTargets extends InputSyncronizedBase {
private final List<Card> choices; private final List<Card> choices;
@@ -47,16 +46,17 @@ public final class InputSelectTargets extends InputSyncronizedBase {
this.tgt = sa.getTargetRestrictions(); this.tgt = sa.getTargetRestrictions();
this.sa = sa; this.sa = sa;
this.mandatory = mandatory; this.mandatory = mandatory;
controller.getGui().setSelectables(CardView.getCollection(choices)); controller.getGui().setSelectables(CardView.getCollection(choices));
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates(); final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
for (final Card c : choices) { for (final Card c : choices) {
zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(),c.getZone().getZoneType())); zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(), c.getZone().getZoneType()));
} }
FThreads.invokeInEdtNowOrLater(new Runnable() { FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public void run() { @Override
controller.getGui().updateZones(zonesToUpdate); public void run() {
controller.getGui().updateZones(zonesToUpdate);
} }
}); });
} }
@Override @Override

View File

@@ -1,14 +1,6 @@
package forge.net; 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 com.google.common.base.Function;
import forge.GuiBase; import forge.GuiBase;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.deck.CardPool; import forge.deck.CardPool;
@@ -22,11 +14,19 @@ import forge.game.spellability.SpellAbilityView;
import forge.interfaces.IGameController; import forge.interfaces.IGameController;
import forge.interfaces.IGuiGame; import forge.interfaces.IGuiGame;
import forge.match.NextGameDecision; import forge.match.NextGameDecision;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection; import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
import forge.util.ReflectionUtil; import forge.util.ReflectionUtil;
import org.apache.commons.lang3.SerializationUtils; 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. * The methods that can be sent through this protocol.
*/ */
@@ -75,8 +75,8 @@ public enum ProtocolMethod {
clearSelectables (Mode.SERVER), clearSelectables (Mode.SERVER),
refreshField (Mode.SERVER), refreshField (Mode.SERVER),
// TODO case "setPlayerAvatar": // TODO case "setPlayerAvatar":
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), openZones (Mode.SERVER, PlayerZoneUpdates.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
restoreOldZones (Mode.SERVER, Void.TYPE, Map/*PlayerView,Object*/.class), restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class),
isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class), isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class),
setRememberedActions(Mode.SERVER, Void.TYPE), setRememberedActions(Mode.SERVER, Void.TYPE),
nextRememberedAction(Mode.SERVER, Void.TYPE), nextRememberedAction(Mode.SERVER, Void.TYPE),

View File

@@ -1,11 +1,6 @@
package forge.net.server; package forge.net.server;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function; import com.google.common.base.Function;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.deck.CardPool; import forge.deck.CardPool;
@@ -23,9 +18,14 @@ import forge.match.AbstractGuiGame;
import forge.net.GameProtocolSender; import forge.net.GameProtocolSender;
import forge.net.ProtocolMethod; import forge.net.ProtocolMethod;
import forge.player.PlayerZoneUpdate; import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection; import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class NetGuiGame extends AbstractGuiGame { public class NetGuiGame extends AbstractGuiGame {
private final GameProtocolSender sender; private final GameProtocolSender sender;
@@ -283,14 +283,14 @@ public class NetGuiGame extends AbstractGuiGame {
} }
@Override @Override
public boolean openZones(final Collection<ZoneType> zones, final Map<PlayerView, Object> players) { public PlayerZoneUpdates openZones(PlayerView controller, final Collection<ZoneType> zones, final Map<PlayerView, Object> players) {
updateGameView(); updateGameView();
return sendAndWait(ProtocolMethod.openZones, zones, players); return sendAndWait(ProtocolMethod.openZones, controller, zones, players);
} }
@Override @Override
public void restoreOldZones(final Map<PlayerView, Object> playersToRestoreZonesFor) { public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) {
send(ProtocolMethod.restoreOldZones, playersToRestoreZonesFor); send(ProtocolMethod.restoreOldZones, playerView, playerZoneUpdates);
} }
@Override @Override

View File

@@ -100,7 +100,7 @@ public class TargetSelection {
return true; return true;
} }
final List<ZoneType> zone = tgt.getZone(); final List<ZoneType> zones = tgt.getZone();
final boolean mandatory = tgt.getMandatory() && hasCandidates; final boolean mandatory = tgt.getMandatory() && hasCandidates;
final boolean choiceResult; final boolean choiceResult;
@@ -110,7 +110,7 @@ public class TargetSelection {
final GameObject choice = Aggregates.random(candidates); final GameObject choice = Aggregates.random(candidates);
return ability.getTargets().add(choice); 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. // If Zone is Stack, the choices are handled slightly differently.
// Handle everything inside function due to interaction with StackInstance // Handle everything inside function due to interaction with StackInstance
return this.chooseCardFromStack(mandatory); return this.chooseCardFromStack(mandatory);
@@ -152,12 +152,15 @@ public class TargetSelection {
for (Card card : validTargets) { for (Card card : validTargets) {
playersWithValidTargets.put(PlayerView.get(card.getController()), null); 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); InputSelectTargets inp = new InputSelectTargets(controller, validTargets, ability, mandatory);
inp.showAndWait(); inp.showAndWait();
choiceResult = !inp.hasCancelled(); choiceResult = !inp.hasCancelled();
bTargetingDone = inp.hasPressedOk(); bTargetingDone = inp.hasPressedOk();
controller.getGui().restoreOldZones(playersWithValidTargets); controller.getGui().restoreOldZones(playerView, playerZoneUpdates);
} }
else { else {
// for every other case an all-purpose GuiChoose // for every other case an all-purpose GuiChoose