mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 10:18:01 +00:00
Merge branch 'master' into 'master'
Select cards from any Zone that can be shown and do arrangeForScry by popping up library and moving cards (in desktop GUI); Pass min/max card selections through to GUI See merge request core-developers/forge!1260
This commit is contained in:
@@ -162,7 +162,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseEntitiesForEffect(
|
||||
FCollectionView<T> optionList, DelayedReveal delayedReveal, SpellAbility sa, String title,
|
||||
FCollectionView<T> optionList, int min, int max, DelayedReveal delayedReveal, SpellAbility sa, String title,
|
||||
Player targetedPlayer) {
|
||||
// this isn't used
|
||||
return null;
|
||||
@@ -1090,7 +1090,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsForZoneChange(
|
||||
ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList,
|
||||
ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, int min, int max,
|
||||
DelayedReveal delayedReveal, String selectPrompt, Player decider) {
|
||||
// this isn't used
|
||||
return null;
|
||||
|
||||
@@ -86,7 +86,7 @@ public class Localizer {
|
||||
resourceBundle = ResourceBundle.getBundle(languageRegionID, new Locale(splitLocale[0], splitLocale[1]), loader);
|
||||
} catch (NullPointerException | MissingResourceException e) {
|
||||
//If the language can't be loaded, default to US English
|
||||
resourceBundle = ResourceBundle.getBundle("en-GB", new Locale("en", "GB"), loader);
|
||||
resourceBundle = ResourceBundle.getBundle("en-US", new Locale("en", "US"), loader);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
@@ -852,7 +852,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
// ensure that selection is within maximum allowed changeNum
|
||||
do {
|
||||
selectedCards = decider.getController().chooseCardsForZoneChange(destination, origin, sa, fetchList, delayedReveal, selectPrompt, decider);
|
||||
selectedCards = decider.getController().chooseCardsForZoneChange(destination, origin, sa, fetchList, 0, changeNum, delayedReveal, selectPrompt, decider);
|
||||
} while (selectedCards != null && selectedCards.size() > changeNum);
|
||||
if (selectedCards != null) {
|
||||
for (Card card : selectedCards) {
|
||||
|
||||
@@ -111,7 +111,7 @@ public abstract class PlayerController {
|
||||
public abstract SpellAbility chooseSingleSpellForEffect(List<SpellAbility> spells, SpellAbility sa, String title,
|
||||
Map<String, Object> params);
|
||||
|
||||
public abstract <T extends GameEntity> List<T> chooseEntitiesForEffect(FCollectionView<T> optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer);
|
||||
public abstract <T extends GameEntity> List<T> chooseEntitiesForEffect(FCollectionView<T> optionList, int min, int max, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer);
|
||||
|
||||
public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message);
|
||||
public abstract boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode bidlife, String string, int bid, Player winner);
|
||||
@@ -239,7 +239,7 @@ public abstract class PlayerController {
|
||||
// better to have this odd method than those if playerType comparison in ChangeZone
|
||||
public abstract Card chooseSingleCardForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional, Player decider);
|
||||
|
||||
public abstract List<Card> chooseCardsForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, Player decider);
|
||||
public abstract List<Card> chooseCardsForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, int min, int max, DelayedReveal delayedReveal, String selectPrompt, Player decider);
|
||||
|
||||
public abstract void autoPassCancel();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FOptionPane;
|
||||
|
||||
import forge.view.arcane.ListCardArea;
|
||||
|
||||
public class GuiChoose {
|
||||
|
||||
@@ -285,5 +285,31 @@ public class GuiChoose {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Card> manipulateCardList(final CMatchUI gui, final String title, final List<Card> cards, final List<Card> manipulable,
|
||||
final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||
final Callable<List<Card>> callable = new Callable<List<Card>>() {
|
||||
@Override
|
||||
public List<Card> call() throws Exception {
|
||||
ListCardArea tempArea = new ListCardArea(gui,title,cards,manipulable,toTop,toBottom,toAnywhere);
|
||||
// tempArea.pack();
|
||||
// window? tempArea.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
tempArea.show();
|
||||
// tempArea.dispose();
|
||||
//try { Thread.sleep(1000); } catch(InterruptedException ex) { }
|
||||
final List<Card> cardList = tempArea.getCardList();
|
||||
return cardList;
|
||||
}
|
||||
};
|
||||
final FutureTask<List<Card>> ft = new FutureTask<List<Card>>(callable);
|
||||
FThreads.invokeInEdtAndWait(ft);
|
||||
try {
|
||||
List<Card> result = ft.get();
|
||||
return result;
|
||||
} catch (final Exception e) { // we have waited enough
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ import forge.deck.Deck;
|
||||
import forge.deckchooser.FDeckViewer;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.GameView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.combat.CombatView;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -101,6 +102,7 @@ import forge.util.gui.SOptionPane;
|
||||
import forge.view.FView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import forge.view.arcane.FloatingCardArea;
|
||||
import forge.match.input.*;
|
||||
|
||||
/**
|
||||
* Constructs instance of match UI controller, used as a single point of
|
||||
@@ -395,7 +397,8 @@ public final class CMatchUI
|
||||
break;
|
||||
case Hand:
|
||||
updateHand = true;
|
||||
//$FALL-THROUGH$
|
||||
updateZones = true;
|
||||
break;
|
||||
default:
|
||||
updateZones = true;
|
||||
FloatingCardArea.refresh(owner, zone);
|
||||
@@ -424,6 +427,57 @@ public final class CMatchUI
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
for (final PlayerZoneUpdate update : zonesToUpdate) {
|
||||
final PlayerView player = update.getPlayer();
|
||||
for (final ZoneType zone : update.getZones()) {
|
||||
switch (zone) {
|
||||
case Battlefield: // always shown
|
||||
break;
|
||||
case Hand: // controller hand always shown
|
||||
if (controller != player) {
|
||||
FloatingCardArea.show(this,player,zone);
|
||||
}
|
||||
break;
|
||||
case Library:
|
||||
case Graveyard:
|
||||
case Exile:
|
||||
case Flashback:
|
||||
case Command:
|
||||
FloatingCardArea.show(this,player,zone);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return zonesToUpdate; //pfps should return only the newly shown zones
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
for (final PlayerZoneUpdate update : zonesToUpdate) {
|
||||
final PlayerView player = update.getPlayer();
|
||||
for (final ZoneType zone : update.getZones()) {
|
||||
switch (zone) {
|
||||
case Battlefield: // always shown
|
||||
break;
|
||||
case Hand: // the controller's hand should never be temporarily shown, but ...
|
||||
case Library:
|
||||
case Graveyard:
|
||||
case Exile:
|
||||
case Flashback:
|
||||
case Command:
|
||||
FloatingCardArea.hide(this,player,zone);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Player's mana pool changes
|
||||
@Override
|
||||
public void updateManaPool(final Iterable<PlayerView> manaPoolUpdate) {
|
||||
@@ -465,6 +519,7 @@ public final class CMatchUI
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FloatingCardArea.refresh(c.getController(),zone); // in case the card is visible in the zone
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -942,11 +997,16 @@ public final class CMatchUI
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameEntityView> chooseEntitiesForEffect(final String title, final List<? extends GameEntityView> optionList, final DelayedReveal delayedReveal) {
|
||||
public List<GameEntityView> chooseEntitiesForEffect(final String title, final List<? extends GameEntityView> optionList, final int min, final int max, final DelayedReveal delayedReveal) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getMessagePrefix(), delayedReveal.getCards()); //TODO: Merge this into search dialog
|
||||
}
|
||||
return (List<GameEntityView>) order(title,"Selected", 0, optionList.size(), optionList, null, null, false);
|
||||
return (List<GameEntityView>) order(title,"Selected", min, max, optionList, null, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||
return GuiChoose.manipulateCardList(this, title, cards, manipulable, toTop, toBottom, toAnywhere);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -246,8 +246,8 @@ public class CardArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
dragPanel.setDisplayEnabled(false);
|
||||
|
||||
CardPanel.setDragAnimationPanel(new CardPanel(dragPanel.getMatchUI(), dragPanel.getCard()));
|
||||
final JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
|
||||
final JLayeredPane layeredPane = frame.getLayeredPane();
|
||||
final RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(this);
|
||||
final JLayeredPane layeredPane = frame.getLayeredPane();
|
||||
layeredPane.add(CardPanel.getDragAnimationPanel());
|
||||
layeredPane.moveToFront(CardPanel.getDragAnimationPanel());
|
||||
final Point p = SwingUtilities.convertPoint(this, this.mouseDragStartX, this.mouseDragStartY, layeredPane);
|
||||
|
||||
@@ -182,6 +182,10 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
});
|
||||
}
|
||||
|
||||
protected boolean cardPanelDraggable(final CardPanel panel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private MouseMotionListener setupMotionMouseListener() {
|
||||
final MouseMotionListener mml = new MouseMotionListener() {
|
||||
@Override
|
||||
@@ -207,20 +211,23 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
if (panel != mouseDownPanel) {
|
||||
return;
|
||||
}
|
||||
if (intialMouseDragX == -1) {
|
||||
intialMouseDragX = x;
|
||||
intialMouseDragY = y;
|
||||
return;
|
||||
}
|
||||
if ((Math.abs(x - intialMouseDragX) < CardPanelContainer.DRAG_SMUDGE)
|
||||
|
||||
if (cardPanelDraggable(panel)) { // allow for non-draggable cards
|
||||
if (intialMouseDragX == -1) {
|
||||
intialMouseDragX = x;
|
||||
intialMouseDragY = y;
|
||||
return;
|
||||
}
|
||||
if ((Math.abs(x - intialMouseDragX) < CardPanelContainer.DRAG_SMUDGE)
|
||||
&& (Math.abs(y - intialMouseDragY) < CardPanelContainer.DRAG_SMUDGE)) {
|
||||
return;
|
||||
}
|
||||
mouseDownPanel = null;
|
||||
setMouseDragPanel(panel);
|
||||
mouseDragOffsetX = panel.getX() - intialMouseDragX;
|
||||
mouseDragOffsetY = panel.getY() - intialMouseDragY;
|
||||
mouseDragStart(getMouseDragPanel(), evt);
|
||||
return;
|
||||
}
|
||||
mouseDownPanel = null;
|
||||
setMouseDragPanel(panel);
|
||||
mouseDragOffsetX = panel.getX() - intialMouseDragX;
|
||||
mouseDragOffsetY = panel.getY() - intialMouseDragY;
|
||||
mouseDragStart(getMouseDragPanel(), evt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -453,4 +460,4 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
this.layoutListeners.add(listener);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,10 @@ public class FloatingCardArea extends CardArea {
|
||||
final FloatingCardArea cardArea = _init(matchUI, player, zone);
|
||||
cardArea.showWindow();
|
||||
}
|
||||
public static void hide(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) {
|
||||
final FloatingCardArea cardArea = _init(matchUI, player, zone);
|
||||
cardArea.hideWindow();
|
||||
}
|
||||
private static FloatingCardArea _init(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) {
|
||||
final int key = getKey(player, zone);
|
||||
FloatingCardArea cardArea = floatingAreas.get(key);
|
||||
@@ -205,6 +209,11 @@ public class FloatingCardArea extends CardArea {
|
||||
window.setFocusableWindowState(false); // should probably do this earlier
|
||||
window.setVisible(true);
|
||||
}
|
||||
private void hideWindow() {
|
||||
onShow();
|
||||
window.setFocusableWindowState(false); // should probably do this earlier
|
||||
window.setVisible(false);
|
||||
}
|
||||
private void showOrHideWindow() {
|
||||
onShow();
|
||||
window.setFocusableWindowState(false); // should probably do this earlier
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.view.arcane;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.view.arcane.util.CardPanelMouseAdapter;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.MouseTriggerEvent;
|
||||
import forge.view.FFrame;
|
||||
import forge.view.FDialog;
|
||||
|
||||
import forge.toolbox.FButton;
|
||||
|
||||
public class ListCardArea extends CardArea {
|
||||
|
||||
private static final String COORD_DELIM = ",";
|
||||
private static final ForgePreferences prefs = FModel.getPreferences();
|
||||
|
||||
public void show() {
|
||||
this.showWindow();
|
||||
}
|
||||
public void hide() {
|
||||
this.hideWindow();
|
||||
}
|
||||
|
||||
private ArrayList<Card> cardList;
|
||||
private ArrayList<Card> moveableCards;
|
||||
private boolean toTop, toBottom, toAnywhere;
|
||||
private String title;
|
||||
private FPref locPref;
|
||||
private boolean hasBeenShown = false, locLoaded;
|
||||
private static ListCardArea storedArea;
|
||||
|
||||
private final FButton doneButton;
|
||||
|
||||
public ListCardArea(final CMatchUI matchUI, final String title0, final List<Card> cardList0, final List<Card> moveableCards0, final boolean toTop0, final boolean toBottom0, final boolean toAnywhere0) {
|
||||
super(matchUI, new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
|
||||
window.add(getScrollPane(),"grow, push");
|
||||
try { Thread.sleep(1000); } catch(InterruptedException ex) { }
|
||||
getScrollPane().setViewportView(this);
|
||||
setOpaque(false);
|
||||
doneButton = new FButton("Done");
|
||||
doneButton.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) { window.setVisible(false); }
|
||||
});
|
||||
window.add(doneButton,BorderLayout.SOUTH);
|
||||
cardList = new ArrayList<Card>(cardList0); // this is modified - pfps - is there a better way?
|
||||
moveableCards = new ArrayList<Card>(moveableCards0);
|
||||
title = title0;
|
||||
toTop = toTop0;
|
||||
toBottom = toBottom0;
|
||||
toAnywhere = toAnywhere0;
|
||||
this.setDragEnabled(true);
|
||||
this.setVertical(true);
|
||||
storedArea = this;
|
||||
}
|
||||
|
||||
public List<Card> getCardList() {
|
||||
return cardList;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
// private SkinnedFrame window = new SkinnedFrame() {
|
||||
private final FDialog window = new FDialog(true, true, "0") {
|
||||
@Override
|
||||
public void setLocationRelativeTo(Component c) {
|
||||
super.setLocationRelativeTo(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b0) {
|
||||
if (isVisible() == b0) { return; }
|
||||
if (b0) {
|
||||
refresh();
|
||||
}
|
||||
super.setVisible(b0);
|
||||
}
|
||||
};
|
||||
|
||||
private void showWindow() {
|
||||
onShow();
|
||||
window.setFocusableWindowState(true);
|
||||
window.setVisible(true);
|
||||
}
|
||||
private void hideWindow() {
|
||||
onShow();
|
||||
window.setFocusableWindowState(false); // should probably do this earlier
|
||||
window.setVisible(false);
|
||||
}
|
||||
private void onShow() {
|
||||
if (!hasBeenShown) {
|
||||
loadLocation();
|
||||
this.addCardPanelMouseListener(new CardPanelMouseAdapter() {
|
||||
@Override
|
||||
public void mouseDragEnd(final CardPanel dragPanel, final MouseEvent evt) {
|
||||
dragEnd(dragPanel);
|
||||
}
|
||||
});
|
||||
this.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent e) {
|
||||
switch (e.getKeyCode()) {
|
||||
case KeyEvent.VK_ENTER:
|
||||
doneButton.doClick();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// is this a valid place to move the card?
|
||||
private boolean validIndex(final Card card, final int index) {
|
||||
if (toAnywhere) { return true; }
|
||||
int oldIndex = cardList.indexOf(card);
|
||||
boolean topMove = true;
|
||||
for(int i=0; i<index+(oldIndex<index?1:0); i++) {
|
||||
if (!moveableCards.contains(cardList.get(i))) { topMove=false; break; }
|
||||
}
|
||||
if (toTop && topMove) { return true; }
|
||||
boolean bottomMove = true;
|
||||
for(int i=index+1-(oldIndex>index?1:0); i<cardList.size(); i++) {
|
||||
if (!moveableCards.contains(cardList.get(i))) { bottomMove=false; break; }
|
||||
}
|
||||
if (toBottom && bottomMove) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Card panelToCard(final CardPanel panel) { //pfps there must be a better way
|
||||
final CardView panelView = panel.getCard();
|
||||
Card panelCard = null;
|
||||
for ( Card card : cardList ) { if ( panelView == card.getView() ) { panelCard = card; } }
|
||||
return panelCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean cardPanelDraggable(final CardPanel panel) {
|
||||
return moveableCards.contains(panelToCard(panel));
|
||||
}
|
||||
|
||||
private void dragEnd(final CardPanel dragPanel) {
|
||||
// if drag is not allowed, don't move anything
|
||||
final Card dragCard = panelToCard(dragPanel);
|
||||
if (moveableCards.contains(dragCard)) {
|
||||
//update index of dragged card in hand zone to match new index within hand area
|
||||
final int index = getCardPanels().indexOf(dragPanel);
|
||||
if (validIndex(dragCard,index)) {
|
||||
synchronized (cardList) {
|
||||
cardList.remove(dragCard);
|
||||
cardList.add(index, dragCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void loadLocation() {
|
||||
if (locPref != null) {
|
||||
String value = prefs.getPref(locPref);
|
||||
if (value.length() > 0) {
|
||||
String[] coords = value.split(COORD_DELIM);
|
||||
if (coords.length == 4) {
|
||||
try {
|
||||
int x = Integer.parseInt(coords[0]);
|
||||
int y = Integer.parseInt(coords[1]);
|
||||
int w = Integer.parseInt(coords[2]);
|
||||
int h = Integer.parseInt(coords[3]);
|
||||
|
||||
//ensure the window is accessible
|
||||
int centerX = x + w / 2;
|
||||
int centerY = y + h / 2;
|
||||
Rectangle screenBounds = SDisplayUtil.getScreenBoundsForPoint(new Point(centerX, centerY));
|
||||
if (centerX < screenBounds.x) {
|
||||
x = screenBounds.x;
|
||||
}
|
||||
else if (centerX > screenBounds.x + screenBounds.width) {
|
||||
x = screenBounds.x + screenBounds.width - w;
|
||||
if (x < screenBounds.x) {
|
||||
x = screenBounds.x;
|
||||
}
|
||||
}
|
||||
if (centerY < screenBounds.y) {
|
||||
y = screenBounds.y;
|
||||
}
|
||||
else if (centerY > screenBounds.y + screenBounds.height) {
|
||||
y = screenBounds.y + screenBounds.height - h;
|
||||
if (y < screenBounds.y) {
|
||||
y = screenBounds.y;
|
||||
}
|
||||
}
|
||||
window.setBounds(x, y, w, h);
|
||||
locLoaded = true;
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
prefs.setPref(locPref, ""); //clear value if invalid
|
||||
prefs.save();
|
||||
}
|
||||
}
|
||||
//fallback default size
|
||||
FFrame mainFrame = Singletons.getView().getFrame();
|
||||
window.setSize(mainFrame.getWidth() / 5, mainFrame.getHeight() / 2);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
List<CardPanel> cardPanels = new ArrayList<CardPanel>();
|
||||
// FCollectionView<Card> cards = new FCollection<Card>(cardList);
|
||||
if (cardList != null) {
|
||||
for (final Card card : cardList) {
|
||||
CardPanel cardPanel = getCardPanel(card.getId());
|
||||
if (cardPanel == null) {
|
||||
cardPanel = new CardPanel(getMatchUI(), card.getView());
|
||||
cardPanel.setDisplayEnabled(true);
|
||||
}
|
||||
else {
|
||||
cardPanel.setCard(card.getView()); //ensure card view updated
|
||||
}
|
||||
cardPanels.add(cardPanel);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hadCardPanels = getCardPanels().size() > 0;
|
||||
setCardPanels(cardPanels);
|
||||
window.setTitle(String.format(title, cardPanels.size()));
|
||||
|
||||
//if window had cards and now doesn't, hide window
|
||||
//(e.g. cast final card from Flashback zone)
|
||||
if (hadCardPanels && cardPanels.size() == 0) {
|
||||
window.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout() {
|
||||
// if (window.isResizing()) {
|
||||
// //delay layout slightly to reduce flicker during window resize
|
||||
// layoutTimer.restart();
|
||||
// }
|
||||
//else {
|
||||
finishDoLayout();
|
||||
//}
|
||||
}
|
||||
|
||||
private final Timer layoutTimer = new Timer(250, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
layoutTimer.stop();
|
||||
finishDoLayout();
|
||||
}
|
||||
});
|
||||
|
||||
private void finishDoLayout() {
|
||||
super.doLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void mouseOver(final CardPanel panel, final MouseEvent evt) {
|
||||
getMatchUI().setCard(panel.getCard(), evt.isShiftDown());
|
||||
super.mouseOver(panel, evt);
|
||||
}
|
||||
@Override
|
||||
public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) {
|
||||
getMatchUI().getGameController().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt));
|
||||
super.mouseLeftClicked(panel, evt);
|
||||
}
|
||||
@Override
|
||||
public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) {
|
||||
getMatchUI().getGameController().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt));
|
||||
super.mouseRightClicked(panel, evt);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseEntitiesForEffect(FCollectionView<T> optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer) {
|
||||
public <T extends GameEntity> List<T> chooseEntitiesForEffect(FCollectionView<T> optionList, int min, int max, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer) {
|
||||
// this isn't used
|
||||
return null;
|
||||
}
|
||||
@@ -624,7 +624,7 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, Player decider) {
|
||||
public List<Card> chooseCardsForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, int min, int max, DelayedReveal delayedReveal, String selectPrompt, Player decider) {
|
||||
// this isn't used
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.deck.CardPool;
|
||||
import forge.deck.FSideboardDialog;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.GameView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.DelayedReveal;
|
||||
@@ -343,6 +344,16 @@ public class MatchController extends AbstractGuiGame {
|
||||
view.updateZones(zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
return view.tempShowZones(controller, zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
view.hideZones(controller, zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCards(final Iterable<CardView> cards) {
|
||||
for (final CardView card : cards) {
|
||||
@@ -506,8 +517,14 @@ public class MatchController extends AbstractGuiGame {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal) {
|
||||
return SGuiChoose.order(title, "Selected", 0, -1, (List<GameEntityView>) optionList, null);
|
||||
public List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, int min, int max, DelayedReveal delayedReveal) {
|
||||
return SGuiChoose.order(title, "Selected", min, max, (List<GameEntityView>) optionList, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||
System.err.println("Not implemented yet - should never be called");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -468,6 +468,15 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
// pfps needs to actually do something
|
||||
return zonesToUpdate; // pfps should return only those zones newly shown
|
||||
}
|
||||
|
||||
public void hideZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
// pfps needs to actually do something
|
||||
}
|
||||
|
||||
public void updateSingleCard(final CardView card) {
|
||||
final CardAreaPanel pnl = CardAreaPanel.get(card);
|
||||
if (pnl == null) { return; }
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.assets.FSkinProp;
|
||||
import forge.deck.CardPool;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.GameView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.DelayedReveal;
|
||||
@@ -47,6 +48,8 @@ public interface IGuiGame {
|
||||
void showManaPool(PlayerView player);
|
||||
void hideManaPool(PlayerView player);
|
||||
void updateStack();
|
||||
Iterable<PlayerZoneUpdate> tempShowZones(PlayerView controller, Iterable<PlayerZoneUpdate> zonesToUpdate);
|
||||
void hideZones(PlayerView controller, Iterable<PlayerZoneUpdate> zonesToUpdate);
|
||||
void updateZones(Iterable<PlayerZoneUpdate> zonesToUpdate);
|
||||
void updateSingleCard(CardView card);
|
||||
void updateCards(Iterable<CardView> cards);
|
||||
@@ -144,7 +147,11 @@ public interface IGuiGame {
|
||||
|
||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
||||
GameEntityView chooseSingleEntityForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal, boolean isOptional);
|
||||
List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal);
|
||||
List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, int min, int max, DelayedReveal delayedReveal);
|
||||
|
||||
// show a list of cards and allow some of them to be moved around and return new list
|
||||
List<Card> manipulateCardList(String title, final List<Card> cards, final List<Card> manipulable, boolean toTop, boolean toBottom, boolean toAnywhere);
|
||||
|
||||
void setCard(CardView card);
|
||||
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
|
||||
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
|
||||
|
||||
@@ -11,12 +11,17 @@ 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;
|
||||
|
||||
public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSelectManyBase<T> {
|
||||
private static final long serialVersionUID = -6609493252672573139L;
|
||||
|
||||
private final FCollectionView<T> validChoices;
|
||||
protected final FCollection<T> selected = new FCollection<T>();
|
||||
protected Iterable<PlayerZoneUpdate> zonesShown; // want to hide these zones when input done
|
||||
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0) {
|
||||
this(controller, min, max, validChoices0, null);
|
||||
@@ -28,6 +33,17 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
if (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()));
|
||||
}
|
||||
PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
|
||||
for (final GameEntity c : validChoices) {
|
||||
final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null ;
|
||||
zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(),cz.getZoneType()));
|
||||
}
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
controller.getGui().updateZones(zonesToUpdate);
|
||||
zonesShown = controller.getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,4 +109,10 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
? String.format(message, selected.size())
|
||||
: String.format(message, max - selected.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
getController().getGui().hideZones(getController().getPlayer().getView(),zonesShown);
|
||||
super.onStop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ public enum ProtocolMethod {
|
||||
hideManaPool (Mode.SERVER, Void.TYPE, PlayerView.class),
|
||||
updateStack (Mode.SERVER),
|
||||
updateZones (Mode.SERVER, Void.TYPE, Iterable/*PlayerZoneUpdate*/.class),
|
||||
tempShowZones (Mode.SERVER, Iterable/*PlayerZoneUpdate*/.class, PlayerView.class, Iterable/*PlayerZoneUpdate*/.class),
|
||||
hideZones (Mode.SERVER, Void.TYPE, PlayerView.class, Iterable/*PlayerZoneUpdate*/.class),
|
||||
updateCards (Mode.SERVER, Void.TYPE, Iterable/*CardView*/.class),
|
||||
updateManaPool (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class),
|
||||
updateLives (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class),
|
||||
@@ -65,7 +67,8 @@ public enum ProtocolMethod {
|
||||
order (Mode.SERVER, List.class, String.class, String.class, Integer.TYPE, Integer.TYPE, List.class, List.class, CardView.class, Boolean.TYPE),
|
||||
sideboard (Mode.SERVER, List.class, CardPool.class, CardPool.class),
|
||||
chooseSingleEntityForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, DelayedReveal.class, Boolean.TYPE),
|
||||
chooseEntitiesForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, DelayedReveal.class),
|
||||
chooseEntitiesForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, Integer.TYPE, Integer.TYPE, DelayedReveal.class),
|
||||
manipulateCardList (Mode.SERVER, List.class, String.class, List.class, List.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE),
|
||||
setCard (Mode.SERVER, Void.TYPE, CardView.class),
|
||||
// TODO case "setPlayerAvatar":
|
||||
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
|
||||
@@ -184,4 +187,4 @@ public enum ProtocolMethod {
|
||||
throw new IllegalStateException(String.format("Protocol method %s: illegal return object type %s returned by client, expected %s", name(), value.getClass().getName(), getReturnType().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.assets.FSkinProp;
|
||||
import forge.deck.CardPool;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.GameView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.DelayedReveal;
|
||||
@@ -147,6 +148,18 @@ public class NetGuiGame extends AbstractGuiGame {
|
||||
send(ProtocolMethod.updateZones, zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PlayerZoneUpdate> tempShowZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
updateGameView();
|
||||
return sendAndWait(ProtocolMethod.tempShowZones, controller, zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideZones(final PlayerView controller, final Iterable<PlayerZoneUpdate> zonesToUpdate) {
|
||||
updateGameView();
|
||||
send(ProtocolMethod.hideZones, controller, zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCards(final Iterable<CardView> cards) {
|
||||
updateGameView();
|
||||
@@ -232,8 +245,13 @@ public class NetGuiGame extends AbstractGuiGame {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameEntityView> chooseEntitiesForEffect(final String title, final List<? extends GameEntityView> optionList, final DelayedReveal delayedReveal) {
|
||||
return sendAndWait(ProtocolMethod.chooseEntitiesForEffect, title, optionList, delayedReveal);
|
||||
public List<GameEntityView> chooseEntitiesForEffect(final String title, final List<? extends GameEntityView> optionList, final int min, final int max, final DelayedReveal delayedReveal) {
|
||||
return sendAndWait(ProtocolMethod.chooseEntitiesForEffect, title, optionList, min, max, delayedReveal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||
return sendAndWait(ProtocolMethod.manipulateCardList, title, cards, manipulable, toTop, toBottom, toAnywhere);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -348,6 +348,31 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return new CardCollection(inp.getSelected());
|
||||
}
|
||||
|
||||
private boolean useSelectCardsInput(final FCollectionView<? extends GameEntity> sourceList) {
|
||||
if ( FThreads.isGuiThread() ) { return false; } // can't use InputSelect from GUI thread (e.g., DevMode Tutor)
|
||||
// if UI_SELECT_FROM_CARD_DISPLAYS not set use InputSelect only for battlefield and player hand
|
||||
// if UI_SELECT_FROM_CARD_DISPLAYS set and using desktop GUI use InputSelect for any zone that can be shown
|
||||
for (final GameEntity c : sourceList) {
|
||||
if (c instanceof Player) {
|
||||
continue;
|
||||
}
|
||||
if (!(c instanceof Card)) {
|
||||
return false;
|
||||
}
|
||||
final Zone cz = ((Card) c).getZone();
|
||||
final boolean useUiPointAtCard =
|
||||
cz != null &&
|
||||
(FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) && (!GuiBase.getInterface().isLibgdxPort()) ) ?
|
||||
(cz.is(ZoneType.Battlefield) || cz.is(ZoneType.Hand) || cz.is(ZoneType.Library) ||
|
||||
cz.is(ZoneType.Graveyard) || cz.is(ZoneType.Exile) || cz.is(ZoneType.Flashback) || cz.is(ZoneType.Command)) :
|
||||
(cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
||||
if (!useUiPointAtCard) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardCollectionView chooseCardsForEffect(final CardCollectionView sourceList, final SpellAbility sa,
|
||||
final String title, final int min, final int max, final boolean isOptional) {
|
||||
@@ -362,22 +387,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
getGui().setPanelSelection(CardView.get(sa.getHostCard()));
|
||||
|
||||
// try to use InputSelectCardsFromList when possible
|
||||
boolean cardsAreInMyHandOrBattlefield = true;
|
||||
for (final Card c : sourceList) {
|
||||
final Zone z = c.getZone();
|
||||
if (z != null && (z.is(ZoneType.Battlefield) || z.is(ZoneType.Hand, player))) {
|
||||
continue;
|
||||
}
|
||||
cardsAreInMyHandOrBattlefield = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cardsAreInMyHandOrBattlefield) {
|
||||
if (useSelectCardsInput(sourceList)) {
|
||||
tempShowCards(sourceList);
|
||||
final InputSelectCardsFromList sc = new InputSelectCardsFromList(this, min, max, sourceList, sa);
|
||||
sc.setMessage(title);
|
||||
sc.setCancelAllowed(isOptional);
|
||||
sc.showAndWait();
|
||||
endTempShowCards();
|
||||
return new CardCollection(sc.getSelected());
|
||||
}
|
||||
|
||||
@@ -411,31 +427,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return Iterables.getFirst(optionList, null);
|
||||
}
|
||||
|
||||
boolean canUseSelectCardsInput = true;
|
||||
for (final GameEntity c : optionList) {
|
||||
if (c instanceof Player) {
|
||||
continue;
|
||||
}
|
||||
final Zone cz = ((Card) c).getZone();
|
||||
// can point at cards in own hand and anyone's battlefield
|
||||
final boolean canUiPointAtCards = cz != null
|
||||
&& (cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
||||
if (!canUiPointAtCards) {
|
||||
canUseSelectCardsInput = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canUseSelectCardsInput) {
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
||||
delayedReveal.getMessagePrefix());
|
||||
}
|
||||
tempShow(optionList);
|
||||
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, isOptional ? 0 : 1, 1,
|
||||
optionList, sa);
|
||||
input.setCancelAllowed(isOptional);
|
||||
input.setMessage(MessageUtil.formatMessage(title, player, targetedPlayer));
|
||||
input.showAndWait();
|
||||
endTempShowCards();
|
||||
return Iterables.getFirst(input.getSelected(), null);
|
||||
}
|
||||
|
||||
@@ -458,7 +461,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseEntitiesForEffect(final FCollectionView<T> optionList,
|
||||
public <T extends GameEntity> List<T> chooseEntitiesForEffect(final FCollectionView<T> optionList, final int min, final int max,
|
||||
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer) {
|
||||
|
||||
// useful details for debugging problems with the mass select logic
|
||||
@@ -475,31 +478,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean canUseSelectCardsInput = true;
|
||||
for (final GameEntity c : optionList) {
|
||||
if (c instanceof Player) {
|
||||
continue;
|
||||
}
|
||||
final Zone cz = ((Card) c).getZone();
|
||||
// can point at cards in own hand and anyone's battlefield
|
||||
final boolean canUiPointAtCards = cz != null
|
||||
&& (cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
||||
if (!canUiPointAtCards) {
|
||||
canUseSelectCardsInput = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canUseSelectCardsInput) {
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
||||
delayedReveal.getMessagePrefix());
|
||||
}
|
||||
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, 0, optionList.size(),
|
||||
tempShow(optionList);
|
||||
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, min, max,
|
||||
optionList, sa);
|
||||
input.setCancelAllowed(true);
|
||||
input.setMessage(MessageUtil.formatMessage(title, player, targetedPlayer));
|
||||
input.showAndWait();
|
||||
endTempShowCards();
|
||||
return (List<T>) input.getSelected();
|
||||
}
|
||||
|
||||
@@ -508,7 +498,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
final List<GameEntityView> chosen = getGui().chooseEntitiesForEffect(title,
|
||||
GameEntityView.getEntityCollection(optionList), delayedReveal);
|
||||
GameEntityView.getEntityCollection(optionList), min, max, delayedReveal);
|
||||
endTempShowCards();
|
||||
|
||||
List<T> results = new ArrayList<>();
|
||||
@@ -747,31 +737,58 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutablePair<CardCollection, CardCollection> arrangeForMove(final String title, final List<Card> cards, final List<Card> manipulable, final boolean topOK, final boolean bottomOK) {
|
||||
List<Card> result = getGui().manipulateCardList("Move cards to top or bottom of library", cards, manipulable, topOK, bottomOK, false);
|
||||
CardCollection toBottom = new CardCollection();
|
||||
CardCollection toTop = new CardCollection();
|
||||
for (int i = 0; manipulable.contains(result.get(i)) && i<cards.size(); i++ ) {
|
||||
toTop.add(result.get(i));
|
||||
}
|
||||
if (toTop.size() < cards.size()) { // the top isn't everything
|
||||
for (int i = result.size()-1; manipulable.contains(result.get(i)); i-- ) {
|
||||
toBottom.add(result.get(i));
|
||||
}
|
||||
}
|
||||
return ImmutablePair.of(toTop,toBottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutablePair<CardCollection, CardCollection> arrangeForScry(final CardCollection topN) {
|
||||
CardCollection toBottom = null;
|
||||
CardCollection toTop = null;
|
||||
|
||||
tempShowCards(topN);
|
||||
if (topN.size() == 1) {
|
||||
if (willPutCardOnTop(topN.get(0))) {
|
||||
toTop = topN;
|
||||
} else {
|
||||
toBottom = topN;
|
||||
}
|
||||
} else {
|
||||
toBottom = game.getCardList(getGui().many("Select cards to be put on the bottom of your library",
|
||||
"Cards to put on the bottom", -1, CardView.getCollection(topN), null));
|
||||
topN.removeAll((Collection<?>) toBottom);
|
||||
if (topN.isEmpty()) {
|
||||
toTop = null;
|
||||
} else if (topN.size() == 1) {
|
||||
toTop = topN;
|
||||
} else {
|
||||
toTop = game.getCardList(getGui().order("Arrange cards to be put on top of your library",
|
||||
"Top of Library", CardView.getCollection(topN), null));
|
||||
}
|
||||
}
|
||||
if ( FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) &&
|
||||
(!GuiBase.getInterface().isLibgdxPort()) ) {
|
||||
ArrayList<Card> cardList = new ArrayList<Card>(); // pfps there must be a better way
|
||||
for (final Card card : player.getCardsIn(ZoneType.Library)) {
|
||||
cardList.add(card);
|
||||
}
|
||||
ImmutablePair<CardCollection, CardCollection> result =
|
||||
arrangeForMove("Move cards to top or bottom of library", cardList, topN, true, true);
|
||||
toTop = result.getLeft();
|
||||
toBottom = result.getRight();
|
||||
} else {
|
||||
if (topN.size() == 1) {
|
||||
if (willPutCardOnTop(topN.get(0))) {
|
||||
toTop = topN;
|
||||
} else {
|
||||
toBottom = topN;
|
||||
}
|
||||
} else {
|
||||
toBottom = game.getCardList(getGui().many("Select cards to be put on the bottom of your library",
|
||||
"Cards to put on the bottom", -1, CardView.getCollection(topN), null));
|
||||
topN.removeAll((Collection<?>) toBottom);
|
||||
if (topN.isEmpty()) {
|
||||
toTop = null;
|
||||
} else if (topN.size() == 1) {
|
||||
toTop = topN;
|
||||
} else {
|
||||
toTop = game.getCardList(getGui().order("Arrange cards to be put on top of your library",
|
||||
"Top of Library", CardView.getCollection(topN), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
endTempShowCards();
|
||||
return ImmutablePair.of(toTop, toBottom);
|
||||
}
|
||||
@@ -1791,9 +1808,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
|
||||
public List<Card> chooseCardsForZoneChange(final ZoneType destination, final List<ZoneType> origin,
|
||||
final SpellAbility sa, final CardCollection fetchList, final DelayedReveal delayedReveal,
|
||||
final SpellAbility sa, final CardCollection fetchList, final int min, final int max, final DelayedReveal delayedReveal,
|
||||
final String selectPrompt, final Player decider) {
|
||||
return chooseEntitiesForEffect(fetchList, delayedReveal, sa, selectPrompt, decider);
|
||||
return chooseEntitiesForEffect(fetchList, min, max, delayedReveal, sa, selectPrompt, decider);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -125,7 +125,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
UI_DISABLE_IMAGES_EFFECT_CARDS("false"),
|
||||
UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED ("Never"),
|
||||
UI_DEFAULT_FONT_SIZE("12"),
|
||||
|
||||
UI_SELECT_FROM_CARD_DISPLAYS("true"),
|
||||
UI_FOR_TOUCHSCREN("false"),
|
||||
|
||||
UI_VIBRATE_ON_LIFE_LOSS("true"),
|
||||
|
||||
Reference in New Issue
Block a user