Commit 234304f9 authored by Peter Patel-Schneider's avatar Peter Patel-Schneider

Add option to select cards from any Zone that can be shown (implemented in...

Add option to select cards from any Zone that can be shown (implemented in desktop GUI only for now)
parent bf59d932
......@@ -101,6 +101,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 +396,8 @@ public final class CMatchUI
break;
case Hand:
updateHand = true;
//$FALL-THROUGH$
updateZones = true;
break;
default:
updateZones = true;
FloatingCardArea.refresh(owner, zone);
......@@ -424,6 +426,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 +518,7 @@ public final class CMatchUI
}
break;
default:
FloatingCardArea.refresh(c.getController(),zone); // in case the card is visible in the zone
break;
}
}
......
......@@ -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
......
......@@ -343,6 +343,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) {
......
......@@ -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; }
......
......@@ -47,6 +47,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);
......
......@@ -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),
......@@ -184,4 +186,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()));
}
}
}
\ No newline at end of file
}
......@@ -147,6 +147,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();
......
......@@ -348,6 +348,30 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return new CardCollection(inp.getSelected());
}
private boolean useSelectCardsInput(final FCollectionView<? extends GameEntity> sourceList) {
// if UI_SELECT_FROM_ZONES not set use InputSelect only for battlefield and player hand
// if UI_SELECT_FROM_ZONES set 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_ZONES) ?
(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 +386,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 +426,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);
}
......@@ -475,31 +477,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());
}
tempShow(optionList);
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, 0, optionList.size(),
optionList, sa);
input.setCancelAllowed(true);
input.setMessage(MessageUtil.formatMessage(title, player, targetedPlayer));
input.showAndWait();
endTempShowCards();
return (List<T>) input.getSelected();
}
......
......@@ -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_ZONES("true"),
UI_FOR_TOUCHSCREN("false"),
UI_VIBRATE_ON_LIFE_LOSS("true"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment